Marimo 노트북과 chDB로 ClickHouse Cloud 데이터 탐색하기
Marimo 노트북과 chDB로 ClickHouse Cloud 데이터 탐색하기
ClickHouse Cloud의 데이터를 Marimo 노트북에서 탐색하는 방법을 배워 봐요. 이 가이드에서는 ClickHouse 기반의 고속 인프로세스 SQL OLAP 엔진인 chDB를 사용해서, 원격 데이터를 Pandas DataFrame으로 가져오고 Plotly로 시각화하며 Marimo의 반응형 실행 모델을 활용하는 흐름을 직접 따라 해 봐요.
출처: 문서
본문
이 가이드에서는 Marimo 노트북에서 chDB 덕분에 ClickHouse Cloud 데이터를 손쉽게 탐색하는 방법을 배워 봐요.
사전 준비 사항:
- Python 3.8 이상
- 가상 환경 (virtual environment)
- 동작 중인 ClickHouse Cloud 서비스와 연결 정보
아직 ClickHouse Cloud 계정이 없다면 가입해서 시작할 수 있어요. 트라이얼에 가입하면 시작할 수 있는 $300 크레딧이 제공돼요.
배우게 될 내용:
- Marimo 노트북에서 chDB를 사용해 ClickHouse Cloud에 연결하기
- 원격 데이터셋 쿼리하고 결과를 Pandas DataFrame으로 변환하기
- Marimo에서 Plotly를 사용해 데이터 시각화하기
- Marimo의 반응형 실행 모델을 활용한 대화형 데이터 탐색하기
ClickHouse Cloud에서 제공하는 스타터 데이터셋 중 하나인 UK Property Price 데이터셋을 사용할 거예요. 이 데이터는 1995년부터 2024년까지 영국에서 판매된 주택 가격에 대한 정보를 담고 있어요.
셋업 (Setup)
데이터셋 로드하기 (Loading the dataset)
기존 ClickHouse Cloud 서비스에 이 데이터셋을 추가하려면 console.clickhouse.cloud에 계정으로 로그인해요. 왼쪽 메뉴에서 Data sources를 클릭하고 Predefined sample data를 선택해요.
UK property price paid data (4GB) 카드에서 Get started를 선택해요.
그다음 Import dataset을 클릭해요.
ClickHouse가 default 데이터베이스에 pp_complete 테이블을 자동으로 생성하고, 2,892만 개의 가격 데이터 행을 채워줘요. 자격 증명이 노출될 가능성을 줄이기 위해, 로컬 머신에서 Cloud 사용자 이름과 비밀번호를 환경 변수로 추가하는 걸 권장해요. 터미널에서 다음 명령을 실행해서 사용자 이름과 비밀번호를 환경 변수로 설정해요.
자격 증명 설정하기 (Setting up credentials)
export CLICKHOUSE_CLOUD_HOSTNAME=<HOSTNAME>
export CLICKHOUSE_CLOUD_USER=default
export CLICKHOUSE_CLOUD_PASSWORD=your_actual_password
위 환경 변수는 터미널 세션이 유지되는 동안만 유효해요. 영구적으로 설정하려면 셸 설정 파일에 추가해 두면 돼요.
Marimo 설치하기 (Installing Marimo)
이제 가상 환경을 활성화해요. 가상 환경 안에서 이 가이드에서 사용할 다음 패키지들을 설치해요:
pip install chdb pandas plotly marimo
다음 명령으로 새 Marimo 노트북을 만들어요:
marimo edit clickhouse_exploration.py
localhost:2718에서 Marimo 인터페이스가 있는 새 브라우저 창이 열릴 거예요.
Marimo 노트북은 순수 Python 파일로 저장돼서, 버전 관리와 공유가 쉬워요.
의존성 설치하기 (Installing dependencies)
새 셀에서 필요한 패키지를 가져와요:
import marimo as mo
import chdb
import pandas as pd
import os
import plotly.express as px
import plotly.graph_objects as go
셀 위에 마우스를 가져가면 ”+” 기호가 있는 원 두 개가 나타나요. 이걸 클릭해서 새 셀을 추가할 수 있어요. 새 셀을 추가하고 간단한 쿼리를 실행해서 모든 게 제대로 설정됐는지 확인해 봐요:
result = chdb.query("SELECT 'Hello ClickHouse from Marimo!'", "DataFrame")
result
방금 실행한 셀 아래에 결과가 표시되는 걸 확인할 수 있어요.
데이터 탐색하기 (Exploring the data)
UK price paid 데이터가 준비되고 Marimo 노트북에서 chDB가 실행되고 있으니, 이제 데이터 탐색을 시작할 차례예요. 영국에서 특정 지역(수도인 런던 같은 곳)의 가격이 시간에 따라 어떻게 변했는지 확인한다고 상상해 봐요.
ClickHouse의 remoteSecure 함수를 사용하면 ClickHouse Cloud에서 데이터를 간편하게 가져올 수 있어요. chDB에 이 데이터를 프로세스 안에서 Pandas 데이터 프레임으로 반환하도록 지시할 수 있는데, 이는 데이터를 다루는 익숙하고 편리한 방식이에요.
ClickHouse Cloud 데이터 쿼리하기 (Querying ClickHouse Cloud data)
ClickHouse Cloud 서비스에서 UK price paid 데이터를 가져와서 pandas.DataFrame으로 바꾸는 다음 쿼리로 새 셀을 만들어요:
query = f"""
SELECT
toYear(date) AS year,
round(avg(price)) AS price,
bar(price, 0, 1000000, 80)
FROM remoteSecure(
'{os.environ.get("CLICKHOUSE_CLOUD_HOSTNAME")}',
'default.pp_complete',
'{os.environ.get("CLICKHOUSE_CLOUD_USER")}',
'{os.environ.get("CLICKHOUSE_CLOUD_PASSWORD")}'
)
WHERE town = 'LONDON'
GROUP BY year
ORDER BY year
"""
df = chdb.query(query, "DataFrame")
df.head()
위 스니펫에서 chdb.query(query, "DataFrame")은 지정한 쿼리를 실행하고 결과를 Pandas DataFrame으로 출력해요. 쿼리에서는 ClickHouse Cloud에 연결하기 위해 remoteSecure 함수를 사용하고 있어요. remoteSecure 함수는 다음을 매개변수로 받아요:
- 연결 문자열
- 사용할 데이터베이스와 테이블 이름
- 사용자 이름
- 비밀번호
보안 모범 사례로, 사용자 이름과 비밀번호 매개변수는 함수에 직접 지정하는 것보다 환경 변수를 사용하는 걸 권장해요. 물론 원하면 직접 지정하는 것도 가능해요.
remoteSecure 함수는 원격 ClickHouse Cloud 서비스에 연결해서 쿼리를 실행하고 결과를 반환해요. 데이터 크기에 따라 몇 초가 걸릴 수도 있어요. 이 경우 연도별 평균 가격 지점을 반환하고 town='LONDON'으로 필터링했어요. 결과는 df라는 변수의 DataFrame에 저장돼요.
데이터 시각화하기 (Visualizing the data)
이제 익숙한 형태로 데이터를 얻었으니, 런던 부동산 가격이 시간에 따라 어떻게 변했는지 살펴볼게요. Marimo는 Plotly 같은 대화형 플로팅 라이브러리와 특히 잘 어울려요. 새 셀에서 대화형 차트를 만들어요:
fig = px.line(
df,
x='year',
y='price',
title='Average Property Prices in London Over Time',
labels={'price': 'Average Price (£)', 'year': 'Year'}
)
fig.update_traces(mode='lines+markers')
fig.update_layout(hovermode='x unified')
fig
놀랍지 않게도, 런던의 부동산 가격은 시간이 지나면서 크게 상승했어요.
Marimo의 강점 중 하나는 반응형 실행 모델이에요. 서로 다른 도시를 동적으로 선택할 수 있는 대화형 위젯을 만들어 볼게요.
대화형 도시 선택 (Interactive town selection)
새 셀에서 서로 다른 도시를 선택할 드롭다운을 만들어요:
town_selector = mo.ui.dropdown(
options=['LONDON', 'MANCHESTER', 'BIRMINGHAM', 'LEEDS', 'LIVERPOOL'],
value='LONDON',
label='Select a town:'
)
town_selector
다른 셀에서 도시 선택에 반응하는 쿼리를 만들어요. 드롭다운을 바꾸면 이 셀이 자동으로 다시 실행돼요:
query_reactive = f"""
SELECT
toYear(date) AS year,
round(avg(price)) AS price
FROM remoteSecure(
'{os.environ.get("CLICKHOUSE_CLOUD_HOSTNAME")}',
'default.pp_complete',
'{os.environ.get("CLICKHOUSE_CLOUD_USER")}',
'{os.environ.get("CLICKHOUSE_CLOUD_PASSWORD")}'
)
WHERE town = '{town_selector.value}'
GROUP BY year
ORDER BY year
"""
df_reactive = chdb.query(query_reactive, "DataFrame")
df_reactive
이제 도시를 바꾸면 자동으로 업데이트되는 차트를 만들어요. 드롭다운이 있는 셀 아래에 차트가 나타나도록, 동적 데이터 프레임 위로 차트를 옮길 수 있어요.
fig_reactive = px.line(
df_reactive,
x='year',
y='price',
title=f'Average Property Prices in {town_selector.value} Over Time',
labels={'price': 'Average Price (£)', 'year': 'Year'}
)
fig_reactive.update_traces(mode='lines+markers')
fig_reactive.update_layout(hovermode='x unified')
fig_reactive
이제 드롭다운에서 도시를 선택하면 차트가 동적으로 업데이트돼요.
대화형 상자 플롯으로 가격 분포 탐색하기 (Exploring price distributions with interactive box plots)
데이터를 더 깊이 들여다보면서, 서로 다른 연도의 런던 부동산 가격 분포를 살펴볼게요. 상자 수염 그림(box and whisker plot)은 중앙값, 사분위수, 이상치를 보여줘서 평균 가격만 볼 때보다 훨씬 잘 이해할 수 있게 해줘요.
먼저 다양한 연도를 대화형으로 탐색할 수 있는 연도 슬라이더를 만들어요. 새 셀에 다음을 추가해요:
year_slider = mo.ui.slider(
start=1995,
stop=2024,
value=2020,
step=1,
label='Select Year:',
show_value=True
)
year_slider
이제 선택한 연도의 개별 부동산 가격을 쿼리해요. 여기서는 집계하지 않는다는 점을 주의해 주세요. 분포를 만들려면 모든 개별 거래가 필요해요:
query_distribution = f"""
SELECT
price,
toYear(date) AS year
FROM remoteSecure(
'{os.environ.get("CLICKHOUSE_CLOUD_HOSTNAME")}',
'default.pp_complete',
'{os.environ.get("CLICKHOUSE_CLOUD_USER")}',
'{os.environ.get("CLICKHOUSE_CLOUD_PASSWORD")}'
)
WHERE town = 'LONDON'
AND toYear(date) = {year_slider.value}
AND price > 0
AND price < 5000000
"""
df_distribution = chdb.query(query_distribution, "DataFrame")
# create an interactive box plot.
fig_box = go.Figure()
fig_box.add_trace(
go.Box(
y=df_distribution['price'],
name=f'London {year_slider.value}',
boxmean='sd', # Show mean and standard deviation
marker_color='lightblue',
boxpoints='outliers' # Show outlier points
)
)
fig_box.update_layout(
title=f'Distribution of Property Prices in London ({year_slider.value})',
yaxis=dict(
title='Price (£)',
tickformat=',.0f'
),
showlegend=False,
height=600
)
fig_box
셀 오른쪽 상단의 옵션 버튼을 선택하면 코드를 숨길 수 있어요. 슬라이더를 움직이면 Marimo의 반응형 실행 덕분에 플롯이 자동으로 업데이트돼요.
요약 (Summary)
이 가이드는 Marimo 노트북에서 chDB를 사용해 ClickHouse Cloud의 데이터를 탐색하는 방법을 보여줬어요. UK Property Price 데이터셋을 사용해, remoteSecure() 함수로 원격 ClickHouse Cloud 데이터를 쿼리하고, 결과를 분석과 시각화를 위해 Pandas DataFrame으로 직접 변환하는 방법을 살펴봤어요. chDB와 Marimo의 반응형 실행 모델을 통해 데이터 과학자들은 Pandas와 Plotly 같은 익숙한 Python 도구와 함께 ClickHouse의 강력한 SQL 기능을 활용할 수 있어요. 여기에 더해 대화형 위젯과 자동 의존성 추적은 탐색적 분석을 더 효율적이고 재현 가능하게 만들어 줘요.