ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • sqlglot, sqlmesh 오픈소스
    공부/데이터 2026. 4. 12. 22:26

    1. 개요

    두 도구는 서로 다른 추상화 수준에서 동작하지만 밀접하게 연관되어 있습니다. SQLGlot은 SQL 조작의 저수준 라이브러리로 활용되며, SQLMesh는 SQLGlot을 기반으로 고수준의 데이터 파이프라인 관리 기능을 제공합니다.

    핵심 개요 비교

    구분 SQLGlot SQLMesh
    유형 SQL 파서/트랜스파일러 라이브러리 데이터 변환 프레임워크
    개발사 Tobiko Data (Toby Mao 개발) Tobiko Data
    GitHub Stars 약 9,100개 약 3,000개
    최신 버전 v30.3.0 (2026년 4월 기준) v0.233.0 (2026년 4월 기준)
    라이선스 MIT Apache 2.0
    Python 요구사항 Python 3.9 이상 Python 3.8 이상
    주요 목적 SQL 파싱, 방언 변환, AST 조작 데이터 파이프라인 관리, CI/CD 자동화
    외부 의존성 없음 (zero dependency) SQLGlot 포함 다수 의존성

    두 도구의 관계

    graph TD
        A["SQLGlot<br>(SQL 파싱/트랜스파일 라이브러리)"] -->|"내장 파서로 사용"| B["SQLMesh<br>(데이터 변환 프레임워크)"]
        B -->|"CI/CD 통합"| C["GitHub Actions / Airflow"]
        B -->|"지원 엔진"| D["BigQuery / Snowflake / Databricks / DuckDB"]
        A -->|"직접 통합"| E["DataHub / OpenLineage / dbt 분석 도구"]

    2. 각 오픈소스 상세 설명

    SQLGlot

    SQLGlot은 외부 의존성이 전혀 없는 순수 Python 기반의 SQL 파서(Parser), 트랜스파일러(Transpiler), 최적화기(Optimizer), 그리고 SQL 실행 엔진입니다. MIT 라이선스로 상업적 사용이 자유롭게 허용됩니다.

    핵심 기능

    기능 설명
    SQL 파싱 SQL 쿼리를 AST(추상 구문 트리)로 변환합니다
    트랜스파일링 한 SQL 방언을 다른 SQL 방언으로 자동 변환합니다 (31개 방언 지원)
    SQL 포맷팅 SQL을 정규화하고 들여쓰기 등의 형식을 일관되게 적용합니다
    AST 조작 파싱된 AST를 순회하거나 변환하는 풍부한 API를 제공합니다
    프로그래밍 방식 SQL 생성 Python 빌더 패턴으로 SQL을 코드에서 동적으로 구성합니다
    쿼리 최적화 논리적 최적화(정규화, 컬럼 자격 부여 등)를 수행합니다
    컬럼 레벨 계보(Lineage) 어떤 컬럼이 어디서 파생됐는지 DAG 형태로 추적합니다
    SQL 실행 엔진 Python dict / Pandas / Arrow를 테이블로 활용해 소규모 SQL을 직접 실행합니다

    지원 SQL 방언 (31개)

    공식 지원 방언 (핵심팀 유지관리): Athena, BigQuery, ClickHouse, Databricks, DuckDB, Hive, MySQL, Oracle, PostgreSQL, Presto, Redshift, Snowflake, Spark, SQLite, Teradata, Trino, T-SQL (Microsoft SQL Server/Azure)

    커뮤니티 지원 방언: Doris, Dremio, Drill, Druid, PRQL, RisingWave, StarRocks 등

    아키텍처 구조

    SQL 문자열
        ↓
    [Tokenizer] → 토큰 시퀀스 (키워드, 식별자, 연산자)
        ↓
    [Parser] → AST (exp.* 노드들, 재귀 하강 파싱)
        ↓
    [Generator] → 목표 방언의 SQL 문자열
    • Tokenizer: 원시 SQL을 어휘 단위(token)로 분리합니다. Python과 Rust 두 가지 구현체를 유지합니다
    • Parser: 토큰을 AST로 변환합니다. 방언별 특수 구문은 Feature Flag와 메서드 오버라이드로 처리합니다
    • Generator: AST 노드를 SQL 문자열로 변환합니다. 방언별 Generator가 상속 방식으로 구분됩니다
    • Optimizer: 논리적 규칙 기반 최적화를 수행합니다 (식별자 정규화, 상수 폴딩 등)
    • Lineage: 쿼리 내 컬럼 의존 관계를 DAG 형태로 추출합니다

    SQLMesh

    SQLMesh는 Tobiko Data가 개발한 차세대 오픈소스 데이터 변환 프레임워크입니다. SQL 또는 Python으로 데이터 변환 모델을 정의하고, 변경 영향 분석·증분 처리·CI/CD 자동화를 통해 데이터 파이프라인을 효율적으로 관리합니다. Linux Foundation 프로젝트로 편입되어 관리되고 있습니다.

    핵심 기능

    기능 설명
    Virtual Data Environment 물리적 데이터 복사 없이 뷰 레이어만으로 즉시 개발 환경을 생성합니다
    Plan/Apply 워크플로우 Terraform과 유사하게 변경 사항을 사전에 검토하고 승인 후 적용합니다
    자동 방언 변환 SQLGlot 기반으로 작성된 SQL을 대상 엔진 방언으로 자동 변환합니다
    증분(Incremental) 처리 변경된 파티션만 재처리하여 컴퓨팅 비용을 절감합니다
    컬럼 레벨 계보 모든 모델에 걸쳐 컬럼 단위의 데이터 계보를 자동 추적합니다
    내장 테스트 및 감사(Audit) 단위 테스트와 데이터 품질 감사를 기본 제공합니다
    GitHub Actions CI/CD 봇 PR 기반 배포 자동화를 기본 내장하고 있습니다
    Python 모델 지원 Pandas/Spark DataFrame을 반환하는 Python 모델을 완전 지원합니다
    웹 UI DAG 시각화, 컬럼 레벨 계보 탐색 UI를 내장하고 있습니다

    dbt 대비 주요 차이점

    기능 dbt Core SQLMesh
    개발 환경 물리적 스키마 전체 재구축 필요 Virtual Data Environment로 즉시 생성 (데이터 복사 없음)
    증분 모델 수동 is_incremental() 매크로 로직 필요 @start_ds, @end_ds 매크로로 자동 처리
    상태 관리 없음 내장 상태 추적 및 관리
    SQL 방언 그대로 사용 (방언 고정) 자동 트랜스파일 (10+ 방언 지원)
    단위 테스트 별도 패키지 필요 내장 지원
    컬럼 레벨 계보 제한적 완전한 컬럼 레벨 lineage 지원
    CI/CD 수동 설정 GitHub Actions 봇 내장
    월 비용 (팀 10명 기준) 기준값 약 1/9 수준

    증분 모델 정의 방식 비교 (dbt vs SQLMesh)

    • dbt 증분 모델 예시
    • -- dbt: 수동으로 is_incremental() 매크로를 사용해야 합니다 SELECT * FROM {{ ref('raw.events') }} e JOIN {{ ref('raw.event_dims') }} d ON e.id = d.id {% if is_incremental() %} AND d.ds >= (SELECT MAX(ds) FROM {{ this }}) {% endif %} {% if is_incremental() %} WHERE e.ds >= (SELECT MAX(ds) FROM {{ this }}) {% endif %}
    • SQLMesh 증분 모델 예시
    • -- SQLMesh: 날짜 범위가 자동으로 처리됩니다 SELECT * FROM raw.events e JOIN raw.event_dims d ON e.id = d.id AND d.ds BETWEEN @start_ds AND @end_ds WHERE d.ds BETWEEN @start_ds AND @end_ds

    3. 사용 방법

    SQLGlot 사용법

    설치

    # 기본 설치 (외부 의존성 없음)
    pip install sqlglot
    
    # C 확장 포함 설치 (파싱 성능 향상)
    pip install "sqlglot[c]"

    SQL 파싱

    import sqlglot
    from sqlglot import parse_one, exp
    
    # 단일 쿼리 파싱
    tree = parse_one("SELECT a, b + 1 AS c FROM d")
    
    # 방언 지정 파싱
    tree = parse_one("SELECT EPOCH_MS(1618088295)", dialect="duckdb")
    
    # 여러 쿼리 파싱
    statements = sqlglot.parse("SELECT * FROM t1; SELECT * FROM t2")

    트랜스파일링 (방언 간 변환)

    import sqlglot
    
    # DuckDB → Hive 변환
    result = sqlglot.transpile(
        "SELECT EPOCH_MS(1618088295)",
        read="duckdb",
        write="hive"
    )[0]
    # 결과: 'SELECT FROM_UNIXTIME(1618088295 / POW(10, 3))'
    
    # BigQuery → Spark 변환 (pretty print)
    sql = "SELECT a, b FROM foo WHERE a = 1"
    result = sqlglot.transpile(sql, write="spark", pretty=True)[0]

    AST 조작

    from sqlglot import parse_one, exp
    
    # 쿼리 내 모든 컬럼 탐색
    for column in parse_one("SELECT a, b + 1 AS c FROM d").find_all(exp.Column):
        print(column.alias_or_name)  # a, b 출력
    
    # 참조된 테이블 탐색
    for table in parse_one("SELECT * FROM x JOIN y JOIN z").find_all(exp.Table):
        print(table.name)  # x, y, z 출력
    
    # AST 변환 (transformer 패턴)
    expression_tree = parse_one("SELECT a FROM x")
    
    def transformer(node):
        if isinstance(node, exp.Column) and node.name == "a":
            return parse_one("FUN(a)")
        return node
    
    transformed_tree = expression_tree.transform(transformer)
    print(transformed_tree.sql())  # 'SELECT FUN(a) FROM x'

    프로그래밍 방식 SQL 생성 (빌더 패턴)

    from sqlglot import select, condition
    
    where = condition("x=1").and_("y=1")
    result = select("*").from_("y").where(where).sql()
    # 결과: 'SELECT * FROM y WHERE x = 1 AND y = 1'

    컬럼 레벨 계보 추출

    from sqlglot.lineage import lineage
    
    node = lineage(
        "a",
        "SELECT a FROM (SELECT x AS a FROM t) subq",
    )
    # 컬럼 'a'가 't.x'에서 파생됐음을 추적합니다

    SQL 최적화

    import sqlglot
    from sqlglot.optimizer import optimize
    
    optimized = optimize(
        sqlglot.parse_one("SELECT A OR (B OR (C AND D)) FROM x WHERE Z = '2021-01-01'"),
        schema={"x": {"A": "INT", "B": "INT", "C": "INT", "D": "INT", "Z": "STRING"}}
    )
    print(optimized.sql(pretty=True))

    내장 SQL 실행 엔진

    import sqlglot
    
    result = sqlglot.execute(
        "SELECT a + 1 AS a FROM x",
        tables={"x": [{"a": 1}, {"a": 2}]}
    )
    # 결과: [{"a": 2}, {"a": 3}]
    # Pandas DataFrame을 테이블로도 사용할 수 있습니다

    SQLMesh 사용법

    설치

    pip install sqlmesh                  # 기본 설치
    pip install 'sqlmesh[lsp]'           # LSP 지원 포함 (추천)
    pip install 'sqlmesh[github]'        # GitHub CI/CD 봇 지원
    pip install 'sqlmesh[dbt]'           # dbt 어댑터 포함
    pip install 'sqlmesh[spark]'         # Spark 지원

    LSP (Language Server Protocol) 지원

    LSP(Language Server Protocol)는 IDE와 언어 도구 서버 사이의 통신 표준 프로토콜입니다. SQLMesh는 LSP를 통해 VS Code 등의 에디터에 SQL 개발 전용 인텔리전트 기능을 제공합니다. pip install 'sqlmesh[lsp]'로 설치한 뒤 SQLMesh VS Code 확장을 함께 설치하면 아래 기능을 사용할 수 있습니다.

    제공되는 기능

    기능 설명
    자동 완성 (Completion) 모델 이름·SQLMesh 키워드·SQL 구문을 타이핑하는 동안 자동 완성 제안
    호버 정보 (Hover) 모델 이름 위에 마우스를 올리면 모델 설명과 메타데이터 즉시 표시
    정의로 이동 (Go to Definition) 모델 참조·CTE·Python 매크로를 Ctrl+Click으로 정의 위치로 바로 이동
    인라인 진단 (Diagnostics) SQLMesh 린터 활성화 시 빌트인·커스텀 규칙 위반을 에디터 내에서 실시간 표시
    포맷팅 (Formatting) SQLMesh 내장 포맷터로 모델 파일을 일관된 스타일로 자동 정리
    계보 시각화 (Lineage) 편집 중인 모델의 컬럼 레벨 계보를 에디터 사이드패널에서 인터랙티브하게 탐색

    LSP를 사용하면 좋은 이유

    • SQL 개발 생산성 향상: 모델 이름·컬럼을 일일이 조회하지 않아도 자동 완성으로 빠르게 작성할 수 있습니다
    • 즉각적인 오류 탐지: 실행 전에 편집기에서 문법 오류나 린트 규칙 위반을 바로 인지합니다
    • 대규모 프로젝트 탐색 용이: 수백 개의 모델이 있어도 정의로 이동 기능으로 의존 모델을 빠르게 찾아볼 수 있습니다
    • 표준 프로토콜 기반: VS Code 외에도 LSP를 지원하는 에디터(Neovim, Emacs 등)에서 동일하게 활용할 수 있습니다

    참고: LSP 서버는 VSCode를 시작한 환경의 환경변수를 상속합니다. CLI에서 설정한 환경변수가 필요하다면 VSCode를 해당 터미널에서 실행하거나, 프로젝트 루트에 .env 파일을 두면 LSP 서버가 자동으로 읽어들입니다.

    프로젝트 초기화

    # DuckDB로 로컬 개발 시작 (추천)
    sqlmesh init duckdb
    
    # 대화형 초기화 (방언 선택 프롬프트)
    sqlmesh init

    SQL 모델 정의

    FULL 모델 (매 실행마다 전체 재구축)

    -- models/full_model.sql
    MODEL (
      name docs_example.full_model,
      kind FULL
    );
    
    SELECT id, name, created_at
    FROM raw.source_table

    INCREMENTAL_BY_TIME_RANGE 모델 (시간 범위 기반 증분)

    -- models/sales_daily.sql
    MODEL (
      name demo.sales_daily,
      kind INCREMENTAL_BY_TIME_RANGE (
        time_column transaction_date,
        lookback 2
      ),
      start '2024-01-01',
      cron '@daily',
      audits (
        UNIQUE_VALUES(columns = (transaction_id)),
        NOT_NULL(columns = (transaction_id))
      )
    );
    
    SELECT
      transaction_id,
      product_id,
      transaction_amount,
      DATE(transaction_timestamp) AS transaction_date
    FROM raw.sales
    WHERE transaction_timestamp BETWEEN @start_dt AND @end_dt

    INCREMENTAL_BY_UNIQUE_KEY 모델 (고유 키 기반 UPSERT)

    MODEL (
      name docs_example.customers,
      kind INCREMENTAL_BY_UNIQUE_KEY (
        unique_key customer_id
      )
    );
    
    SELECT customer_id, name, email, updated_at
    FROM raw.customers

    Python 모델 정의

    # models/python_model.py
    import typing as t
    from datetime import datetime
    import pandas as pd
    from sqlmesh import ExecutionContext, model
    from sqlmesh.core.model.kind import ModelKindName
    
    @model(
        "docs_example.incremental_model",
        kind=dict(
            name=ModelKindName.INCREMENTAL_BY_TIME_RANGE,
            time_column="model_time_column"
        )
    )
    def execute(
        context: ExecutionContext,
        start: datetime,
        end: datetime,
        **kwargs: t.Any,
    ) -> pd.DataFrame:
        df = context.table("raw.source_table")
        return df[(df["ds"] >= start) & (df["ds"] < end)]

    지원 모델 종류 (Model Kinds)

    Kind 설명
    FULL 매 실행마다 전체 테이블 재구축합니다
    INCREMENTAL_BY_TIME_RANGE 시간 범위 기반 증분 처리합니다
    INCREMENTAL_BY_UNIQUE_KEY 고유 키 기반 UPSERT 증분 처리합니다
    SCD_TYPE_2 Slowly Changing Dimension Type 2를 지원합니다
    VIEW 데이터베이스 뷰를 생성합니다
    SEED CSV 등 정적 데이터를 로드합니다
    EXTERNAL 외부 테이블을 참조합니다

    주요 CLI 명령어

    sqlmesh plan                    # prod 환경 플랜 생성 및 적용
    sqlmesh plan dev                # dev 환경 플랜 생성 및 적용
    sqlmesh run                     # 스케줄 기반 모델 실행
    sqlmesh ui                      # 웹 UI 실행 (DAG 시각화, lineage 탐색)
    sqlmesh test                    # 단위 테스트 실행
    sqlmesh audit                   # 데이터 품질 감사 실행
    sqlmesh fetchdf "SELECT * FROM model LIMIT 10"
    sqlmesh state export --environment dev -o state.json
    sqlmesh dag output.html         # DAG 시각화 HTML 파일 생성

    4. 언제 사용하면 좋은가

    SQLGlot을 사용해야 할 때

    유스케이스 설명
    SQL 방언 마이그레이션 Oracle/Teradata → BigQuery/Snowflake 이전 시 수백 개의 SQL 파일을 자동 변환합니다
    SQL 분석 도구 개발 참조 테이블, 사용된 컬럼, JOIN 관계를 자동 추출하는 메타데이터 파이프라인을 구축합니다
    컬럼 레벨 계보 추출 DataHub, OpenLineage 등 계보 시스템과 통합하여 컬럼 계보 그래프를 구성합니다
    SQL 단위 테스트 실제 데이터 웨어하우스 없이 Python dict/Pandas로 SQL 로직을 검증합니다
    SQL 포맷터/린터 구축 팀 내 SQL 스타일 가이드를 강제하는 자동화 도구를 구현합니다
    다중 방언 추상화 레이어 다양한 SQL 방언 입력을 단일 내부 표현으로 정규화하는 레이어를 구축합니다

    SQLGlot 사용 시 주요 이점

    • zero dependency: 외부 라이브러리 없이 pip install sqlglot만으로 즉시 사용 가능합니다
    • 가장 빠른 순수 Python SQL 파서: sqlparse, sqlfluff 등 대비 현저히 빠른 성능을 자랑합니다
    • 완전한 AST 접근: 파싱 결과를 세밀하게 조작할 수 있습니다
    • 31개 방언 지원: 업계에서 가장 넓은 방언 커버리지를 보유하고 있습니다
    • MIT 라이선스: 상업적 사용에 제약이 없습니다

    SQLMesh를 사용해야 할 때

    유스케이스 설명
    비용 효율적 개발 환경 대용량 데이터 웨어하우스에서 개발 환경 복사 비용이 과다한 팀에 적합합니다
    멀티 엔진 환경 Snowflake, BigQuery, Databricks 등 여러 플랫폼을 동시 사용하거나 마이그레이션을 계획 중인 팀에 적합합니다
    대규모 파이프라인 운영 수백 개의 모델을 관리하며 변경 영향 분석과 안전한 배포가 중요한 팀에 적합합니다
    dbt 마이그레이션 고려 기존 dbt 프로젝트를 SQLMesh에서 실행할 수 있는 어댑터를 제공하여 점진적 마이그레이션이 가능합니다
    엄격한 데이터 품질 요구 금융, 헬스케어 등 데이터 정확성이 중요한 도메인에서 감사(Audit)와 단위 테스트 기능이 유용합니다
    컬럼 레벨 거버넌스 규제 준수나 데이터 거버넌스 요구사항이 있을 때 컬럼 레벨 계보 기능이 필수적으로 활용됩니다

    SQLMesh 사용 시 주요 이점

    • 컴퓨팅 비용 절감: 팀 10명, 월 30회 배포 기준 dbt 대비 약 1/9 수준의 비용이 소요됩니다
    • 개발 속도 향상: Virtual Data Environment로 개발 환경 생성 시간이 제거됩니다 (월 약 300시간 절약 추정)
    • 안전한 배포: Plan/Apply 패턴으로 변경 영향을 사전에 파악하고 배포합니다
    • 자동 의존성 관리: SQL 파싱을 통해 모델 간 의존성이 자동으로 탐지됩니다
    • 하위 호환성: 기존 dbt 프로젝트를 SQLMesh에서 그대로 실행 가능합니다

    5. 연동 및 확장 시나리오

    SQLGlot 연동 시나리오

    dbt와의 통합

    dbt 모델(.sql 파일)을 파싱하여 컬럼 레벨 계보를 추출하는 데 SQLGlot이 활용됩니다. Jinja 템플릿 처리 이후의 순수 SQL에 SQLGlot을 적용하여 방언 변환이나 분석을 수행합니다.

    DataHub / OpenLineage와의 통합

    DataHub는 SQLGlot을 사용하여 SQL 쿼리에서 컬럼 레벨 계보를 추출합니다. OpenLineage 생태계에서도 SQL 파싱 백엔드로 SQLGlot이 활용되고 있습니다.

    Pandas / Arrow와의 통합

    import sqlglot
    
    # Python dict를 테이블로 사용하여 SQL 실행
    result = sqlglot.execute(
        "SELECT a + 1 AS a FROM x WHERE a > 1",
        tables={"x": [{"a": 1}, {"a": 2}, {"a": 3}]}
    )
    # Pandas DataFrame도 테이블로 사용 가능합니다

    커스텀 방언 확장

    from sqlglot.dialects import MySQL
    
    class MyCustomDialect(MySQL):
        class Generator(MySQL.Generator):
            TRANSFORMS = {
                **MySQL.Generator.TRANSFORMS,
                # 조직 내 커스텀 함수 변환 규칙 추가
            }

    SQLMesh 연동 시나리오

    지원 실행 엔진

    엔진 지원 여부 비고
    BigQuery 지원  
    Databricks 지원 상태 저장은 DuckDB 별도 설정 권장
    DuckDB 지원 로컬 개발 기본값 (강력 추천)
    Snowflake 지원  
    Redshift 지원  
    Trino 지원  
    Spark 지원 상태 연결에는 미권장, DuckDB 별도 구성 필요
    PostgreSQL 지원  
    ClickHouse 지원  
    Microsoft Fabric 지원  

    GitHub Actions CI/CD 통합

    # .github/workflows/sqlmesh.yml
    name: SQLMesh Bot
    on:
      pull_request:
        types: [synchronize, opened]
    
    jobs:
      sqlmesh:
        runs-on: ubuntu-latest
        permissions:
          contents: write
          pull-requests: write
        steps:
          - uses: actions/checkout@v4
          - run: pip install -r requirements.txt
          - run: sqlmesh_cicd -p ${{ github.workspace }} github --token ${{ secrets.GITHUB_TOKEN }} run-all

    PR이 생성되거나 업데이트될 때 자동으로 dev 환경을 생성하고, 변경 영향을 분석하며, 승인 후 프로덕션에 블루/그린 배포를 수행합니다.

    Databricks 상태 저장 설정

    # config.yaml
    gateway:
      databricks:
        type: databricks
        state_connection:
          type: duckdb
          database: databricks_state.db

    Jupyter Notebook 통합

    # Jupyter Notebook에서 SQLMesh를 초기화하여 사용합니다
    %init path_to_project_directory snowflake

    6. 두 오픈소스의 차이점

    SQLGlot과 SQLMesh는 같은 팀에서 개발되었지만 서로 다른 수준에서 동작하는 도구입니다. SQLGlot은 SQLMesh의 기반 기술로 내장되어 있으며, 두 도구는 경쟁 관계가 아니라 상호 보완적인 관계입니다.

    구분 SQLGlot SQLMesh
    추상화 수준 저수준 (SQL 조작 라이브러리) 고수준 (데이터 파이프라인 프레임워크)
    주요 사용자 개발자, 도구 제작자, 데이터 엔지니어 데이터 팀, 데이터 엔지니어링 팀
    기능 범위 SQL 파싱, 변환, AST 조작, 계보 추출 모델 관리, 환경 격리, CI/CD, 스케줄링
    설치 복잡도 단순 (pip install sqlglot, 의존성 없음) 상대적으로 복잡 (프로젝트 구조 초기화 필요)
    학습 곡선 낮음 (Python 라이브러리 API 학습) 중간~높음 (Plan/Apply, VDE 등 개념 학습 필요)
    데이터 웨어하우스 연동 없음 (순수 SQL 텍스트 조작) 10+ 엔진 직접 연동
    상태 관리 없음 내장 상태 추적 및 관리
    웹 UI 없음 내장 (DAG, Lineage 시각화)
    CI/CD 지원 없음 (라이브러리 자체에는 없음) GitHub Actions 봇 내장
    커스터마이징 방언 클래스 직접 확장 가능, 매우 유연 프레임워크 내 방식으로만 확장 가능
    라이선스 MIT Apache 2.0
    GitHub Stars 약 9,100개 약 3,000개

    7. Python SQLGlot 라이브러리 단독 사용 vs SQLMesh

    관점 SQLGlot 단독 사용 SQLMesh (SQLGlot 내장)
    사용 목적 SQL 파싱/변환/분석 작업 자체 데이터 파이프라인 전체 생명주기 관리
    제어 수준 AST 수준의 세밀한 직접 제어 가능 SQLMesh가 SQLGlot을 내부적으로 처리, 직접 제어 불가
    적합한 사용자 SQL 조작 도구를 직접 개발하는 개발자 데이터 변환 파이프라인을 관리하는 데이터 팀
    방언 변환 명시적 API 호출로 직접 변환 수행 자동으로 대상 엔진 방언으로 변환
    컬럼 계보 lineage() API를 직접 호출하여 추출 모든 모델에 자동 적용, UI에서 시각화
    설치 pip install sqlglot (의존성 없음) pip install sqlmesh (다수 의존성 포함)
    학습 비용 낮음 (Python 라이브러리 API 학습) 높음 (프레임워크 전체 개념 학습 필요)
    커스터마이징 방언 클래스 직접 확장, 파이프라인 자유롭게 구성 프레임워크가 제공하는 방식으로만 확장 가능
    상태/환경 관리 없음 (라이브러리 수준) 내장 상태 관리 및 Virtual Data Environment 제공

    선택 기준

    SQLGlot 단독 사용이 적합한 경우

    • 사내 SQL 분석 도구나 린터를 직접 개발하는 경우입니다
    • 여러 SQL 방언을 자동 변환하는 마이그레이션 스크립트가 필요한 경우입니다
    • DataHub, OpenLineage 등 기존 데이터 도구에 SQL 파싱 기능을 통합하는 경우입니다
    • 데이터 파이프라인 없이, SQL 텍스트 수준의 조작만 필요한 경우입니다

    SQLMesh 사용이 적합한 경우

    • 데이터 변환 모델(ELT 파이프라인)을 팀 단위로 관리하는 경우입니다
    • 개발/프로덕션 환경 분리와 CI/CD 자동화가 필요한 경우입니다
    • dbt를 사용 중이고 더 강력한 기능과 비용 절감이 필요한 경우입니다
    • SQL/Python 모델을 하나의 프레임워크로 통합 관리하고 싶은 경우입니다

    8. 성능 및 비용 분석

    SQLGlot 성능

    SQLGlot은 순수 Python SQL 파서 중 가장 빠른 성능을 제공합니다.

    • sqlparse, sqlfluff 등 다른 Python 기반 파서 대비 현저히 빠른 성능을 자랑합니다
    • C 확장 설치 시(pip install "sqlglot[c]") 파싱 성능이 크게 향상됩니다
    • Rust 바인딩 기반 파서(sqloxide 등)에 비해 raw 파싱 성능은 낮습니다
    • 내장 SQL 실행 엔진은 100만 행 이상의 대용량 데이터에는 적합하지 않습니다

    SQLMesh 비용 절감 효과

    Databricks 환경에서 dbt Core 대비 수행한 벤치마크 결과, SQLMesh가 수배~수십 배 빠른 실행 속도를 보였습니다.

    비용 요소 dbt Core SQLMesh
    개발 환경 생성 물리적 스키마 복사 필요 (비용 발생) 데이터 복사 없이 뷰 생성 (비용 거의 없음)
    증분 처리 효율 수동 설정 필요, 비효율적 재처리 가능성 자동 최적화 (최소한의 파티션만 재처리)
    월 비용 (팀 10명, 30회 배포 기준) 기준값 약 1/9 수준
    개발자 시간 절약 기준값 월 약 300시간 절약 추정

    9. 주의사항 및 제한사항

    SQLGlot 주의사항

    • SQL 검증이 목표가 아님: 일부 문법 오류가 감지되지 않고 통과될 수 있으므로 엄격한 SQL 검증에는 별도 도구를 병행해야 합니다
    • 실행 엔진 성능 한계: 내장 실행 엔진은 100만 행 이상의 대용량 데이터 처리에 적합하지 않습니다. 프로덕션 쿼리 실행에는 DuckDB, Spark 등의 전용 엔진을 사용해야 합니다
    • 논리적 최적화만 수행: Optimizer는 AST 수준의 논리적 최적화만 수행하며, 실제 실행 계획 최적화는 각 DB 엔진이 담당합니다
    • 커뮤니티 방언 품질 편차: Doris, Druid, PRQL 등 커뮤니티 방언은 공식 방언 대비 버그 수정이 늦을 수 있습니다
    • PySpark DataFrame API 분리: v24부터 PySpark DataFrame API가 SQLFrame 독립 라이브러리로 분리되었으므로 마이그레이션이 필요합니다

    SQLMesh 주의사항

    • 가파른 학습 곡선: Plan/Apply 패턴, Virtual Data Environment, 상태 관리 방식이 dbt에 익숙한 엔지니어에게는 낯설 수 있습니다
    • 작은 생태계: dbt에 비해 커뮤니티 규모가 작고, 서드파티 통합 패키지가 부족합니다
    • 레거시 시스템 호환성: 기존 데이터 아키텍처와의 통합 과정에서 호환성 문제가 발생할 수 있습니다
    • Spark 상태 저장 제한: Spark를 상태 연결로 사용하는 것은 권장되지 않으며, DuckDB 등 별도 상태 저장소를 구성해야 합니다
    • 빠른 릴리스 주기: v0.233.0까지 522번의 릴리스가 있을 만큼 빠르게 변경되므로 버전 고정과 업그레이드 관리에 주의가 필요합니다
    • dbt 완전 대체 시 주의: 일부 고급 dbt 기능은 SQLMesh에서 완전히 동일하게 동작하지 않을 수 있습니다

    10. 결론

    핵심 요약

    도구 선택 가이드

    상황 권장 도구
    SQL 방언 간 자동 변환 스크립트 개발 SQLGlot
    SQL 분석/린터 도구 개발 SQLGlot
    DataHub/OpenLineage에 계보 추출 통합 SQLGlot
    데이터 변환 파이프라인(ELT) 관리 SQLMesh
    dbt에서 마이그레이션 고려 SQLMesh
    여러 데이터 웨어하우스 동시 지원 필요 SQLMesh
    데이터 파이프라인 CI/CD 자동화 SQLMesh
    두 가지 모두 필요한 엔터프라이즈 환경 SQLMesh (SQLGlot 내장)

    최종 권고

    SQLGlot과 SQLMesh는 경쟁 관계가 아니라 상호 보완적인 관계입니다. SQL 조작과 분석 도구 개발이 주된 목적이라면 SQLGlot을, 데이터 파이프라인의 전체 라이프사이클 관리가 목적이라면 SQLMesh를 선택하는 것이 바람직합니다.

    많은 엔터프라이즈 환경에서는 SQLGlot으로 저수준 SQL 분석을 처리하면서 SQLMesh로 고수준 파이프라인을 관리하는 조합을 성공적으로 활용하고 있습니다. 특히 데이터 웨어하우스 마이그레이션을 계획 중인 팀이라면 SQLMesh + SQLGlot 조합이 가장 강력한 선택입니다.


    참고 문서

    댓글