---
title: 모델 작성
description: 모델은 파일에 담긴 select 문입니다. Supernova는 이를 테이블로 구체화하고 종속성 순서에 따라 갱신합니다.
species: guide
---

# 모델 작성

모델은 `select` 문 1개를 담은 `.sql` 파일입니다. Supernova는 이를 레이크의 테이블로 구체화하고 다른 모든 모델과 함께 종속성 순서대로 4시간마다 다시 빌드합니다. 설정 파일이나 별도로 구성할 스케줄러는 없습니다. SQL 자체가 전체 정의입니다.

## 모델의 위치

모델은 데이터 저장소의 `models/` 아래에 있는 파일입니다. **파일** 페이지에서 편집하거나 저장소를 복제해 원하는 편집기를 사용하세요. 어느 쪽이든 Git을 사용하며 전체 이력이 남습니다.

```text
models/
  monthly_revenue.sql
  revenue/
    active_subscriptions.sql
    churn_risk.sql
```

**기본 파일 이름이 테이블 이름입니다.** `models/revenue/churn_risk.sql`은 `churn_risk`라는 테이블로 구체화됩니다. 폴더는 파일을 정리하는 용도이며 테이블 이름을 바꾸지 않습니다.

## 완전한 모델

```sql run
-- name: Active subscriptions
-- schema: revenue
select
  s.id,
  s.customer_id,
  c.email,
  s.status,
  s.created_at
from titan.stripe.subscriptions s
join titan.stripe.customers c on c.id = s.customer_id
where s.status in ('active', 'past_due')
  and not s._deleted
```

이 모델은 동기화된 테이블처럼 쿼리할 수 있는 `revenue.active_subscriptions`를 만듭니다. `-- schema:` 줄이 없으면 기본 `models` 스키마에 생성됩니다.

모델은 다른 모델의 테이블 이름을 지정해 조회할 수 있습니다. Supernova는 SQL을 읽고 종속성 그래프를 만들어 올바른 순서로 모두 실행합니다. **자신의** 출력 테이블을 읽는 모델은 이전 실행의 결과를 읽는 것으로 해석되며, 이를 통해 누적 합계나 점진적으로 쌓이는 이력을 만들 수 있습니다.

## 헤더 지시문

지시문은 파일의 첫 20줄에 있는 주석 줄입니다. 모두 선택 사항입니다.

| 지시문 | 효과 |
|---|---|
| `-- name: Monthly revenue` | 파일 탐색기와 실행 기록에 표시할 이름 |
| `-- schema: revenue` | 출력 스키마. 기본값은 `models`이며 소문자를 사용하고 동기화된 소스의 스키마를 가릴 수 없음 |
| `-- cadence: manual` | 예약 실행에서 제외하고 직접 실행할 때만 다시 빌드 |
| `-- depends_on: stripe.charges` | SQL만으로 드러나지 않는 종속성 추가 |
| `-- unique_key: id` | 전체 다시 빌드 대신 키 기반 증분 업데이트. 아래 설명 참고 |
| `-- lint:` | 모델별 진단 정책. 줄마다 `TS0000: allow` 또는 `deny` 지정 |

형식이 잘못된 지시문은 일부만 동작하지 않습니다. 해당 줄을 명시하는 오류와 함께 모델 실행을 거부합니다. 오타를 조용히 무시하는 것보다 명확하게 중단하는 편이 낫습니다.

## 다시 빌드 또는 업서트

기본적으로 매 실행은 모델 테이블을 처음부터 다시 빌드합니다. 가장 단순하며 대부분의 모델에 적합합니다. 키를 선언하면 전략이 바뀝니다.

```sql fragment
-- unique_key: id
```

이제 매 실행은 해당 키로 **업서트**합니다. 키가 일치하는 행은 대체하고, 새 행은 추가하며, 나머지는 그대로 둡니다. 전체 빌드 시 다시 계산해야 할 이력을 누적하거나, 테이블을 지켜보는 후속 도구에 빌드 도중 테이블이 사라지는 모습을 보여주면 안 될 때 사용하세요.

## 실행

4시간마다 조직당 1회의 실행이 모든 모델을 종속성 순서대로 실행합니다. 그래프가 허용하면 최대 4개를 동시에 실행합니다. **모델** 페이지에는 그래프, 각 모델의 마지막 결과, **지금 실행** 버튼이 표시됩니다. 실행 중인 모델에는 최대 4시간이 주어지며, 이를 넘으면 실패로 표시하고 해당 모델에 종속되지 않은 모델을 계속 처리합니다.

## 타입 검사

모든 모델은 실행 전에 레이크의 실제 스키마를 기준으로 검사됩니다. 편집기와 같은 검사기를 사용하므로 소스에서 열이 삭제되거나 상위 모델의 타입이 바뀌면 대시보드가 깨진 뒤 알아내는 대신 이름이 있는 진단으로 감지합니다. `-- lint:` 헤더로 모델별 심각도를 조정합니다.

```sql fragment
-- lint:
--   TS0400: allow
--   TS0609: deny
```

`allow`는 진단을 경고로 낮추고 `deny`는 실행을 막는 오류로 높입니다. 특히 의존하는 표현식에 [타입 어노테이션](/docs/typesql/annotations)을 추가하면 검사기가 실행할 때마다 그 조건을 확인합니다.
