> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sifi.life/llms.txt
> Use this file to discover all available pages before exploring further.

# Lakebase 연동

> 이 문서는 **[Databricks Apps](/blog/guides/apps/overview)** 섹션의 일부입니다.

**Lakebase** 는 Databricks가 관리하는 PostgreSQL 데이터베이스입니다. Databricks Apps에서 **OLTP(트랜잭션) 워크로드** 를 처리할 때 적합합니다.

***

## 왜 Lakebase인가?

| 비교 항목     | Unity Catalog 테이블           | Lakebase              |
| --------- | --------------------------- | --------------------- |
| **접근 방식** | SQL Warehouse를 통한 분석 쿼리     | 직접 PostgreSQL 연결      |
| **지연 시간** | 수백 ms\~수 초 (Warehouse 오버헤드) | 수 ms\~수십 ms           |
| **용도**    | 분석, 대시보드, 배치 처리             | CRUD, 세션 관리, 실시간 데이터  |
| **트랜잭션**  | 제한적                         | 완전한 ACID 트랜잭션         |
| **스키마**   | Delta Lake (읽기 최적화)         | PostgreSQL (쓰기/읽기 균형) |

***

## Lakebase 리소스 설정

**app.yaml:**

```yaml theme={null}
command: ['python', 'app.py']
env:
  - name: DB_CONNECTION
    valueFrom: lakebase_db
resources:
  - name: lakebase_db
    type: postgres
```

### 필수 패키지

```text theme={null}
# requirements.txt
databricks-sdk
psycopg2-binary    # PostgreSQL 드라이버
```

***

## Python 연결 예시

```python theme={null}
import os
import psycopg2

# Lakebase 연결 정보 가져오기
db_connection = os.getenv("DB_CONNECTION")

# PostgreSQL 연결
conn = psycopg2.connect(db_connection)

# CRUD 작업
with conn.cursor() as cur:
    # 테이블 생성
    cur.execute("""
        CREATE TABLE IF NOT EXISTS app_sessions (
            id SERIAL PRIMARY KEY,
            user_id VARCHAR(255),
            data JSONB,
            created_at TIMESTAMP DEFAULT NOW()
        )
    """)

    # 데이터 삽입
    cur.execute(
        "INSERT INTO app_sessions (user_id, data) VALUES (%s, %s)",
        ("user123", '{"page": "dashboard", "action": "view"}')
    )
    conn.commit()

    # 데이터 조회
    cur.execute("SELECT * FROM app_sessions WHERE user_id = %s", ("user123",))
    rows = cur.fetchall()

conn.close()
```

***

## Streamlit + Lakebase 예시

```python theme={null}
import os
import streamlit as st
import psycopg2

@st.cache_resource
def get_db_connection():
    """Lakebase 연결을 캐싱하여 재사용합니다."""
    return psycopg2.connect(os.getenv("DB_CONNECTION"))

conn = get_db_connection()

st.title("피드백 수집 앱")

# 피드백 입력 폼
with st.form("feedback_form"):
    name = st.text_input("이름")
    feedback = st.text_area("피드백")
    rating = st.slider("만족도", 1, 5, 3)
    submitted = st.form_submit_button("제출")

    if submitted:
        with conn.cursor() as cur:
            cur.execute(
                "INSERT INTO feedback (name, feedback, rating) VALUES (%s, %s, %s)",
                (name, feedback, rating)
            )
            conn.commit()
        st.success("피드백이 저장되었습니다!")

# 피드백 목록 조회
with conn.cursor() as cur:
    cur.execute("SELECT name, feedback, rating, created_at FROM feedback ORDER BY created_at DESC LIMIT 20")
    rows = cur.fetchall()

if rows:
    import pandas as pd
    df = pd.DataFrame(rows, columns=["이름", "피드백", "만족도", "작성일"])
    st.dataframe(df)
```

> **주의**
> **OAuth 토큰 로테이션**: Lakebase 연결은 OAuth 역할 인증을 사용하며, 토큰은 **1시간 후 만료** 됩니다. 장기 실행 앱에서는 자동 토큰 갱신을 구현하거나, 연결 풀에서 주기적으로 연결을 재생성해야 합니다. 토큰이 만료되면 연결이 끊어집니다.

***

## Lakebase 사용 시나리오

| 시나리오          | 왜 Lakebase가 적합한가       |
| ------------- | ---------------------- |
| **사용자 설정 저장** | 빠른 읽기/쓰기, 세션 간 영속성     |
| **피드백/설문 수집** | ACID 트랜잭션으로 데이터 무결성 보장 |
| **채팅 이력 저장**  | 실시간 쓰기, 사용자별 격리        |
| **앱 메타데이터**   | 설정, 상태, 캐시 등 앱 내부 데이터  |
| **큐/태스크 관리**  | 작업 큐, 상태 추적, 워크플로우     |

> **참고**
> **Lakebase vs UC 테이블 선택 기준**: "앱 내부에서만 사용하는 운영 데이터"는 Lakebase, "분석이나 ML에 활용할 데이터"는 UC 테이블에 저장하세요. 물론 Lakebase의 데이터를 Delta Live Tables(DLT)로 UC 테이블에 동기화하는 것도 가능합니다.
