ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] sqlfluff 사용법
    언어/파이썬 & 장고 2025. 8. 31. 16:50

    SQLFluff란 무엇인가?

    SQLFluff는 Python으로 작성된 SQL 린터이자 포매터입니다. SQL 코드의 품질을 향상시키고 일관된 스타일을 유지하는 데 도움을 주는 도구로 다양한 SQL 방언(dialect)을 지원합니다.

    주요 특징

    • 다중 방언 지원: PostgreSQL, MySQL, SQLite, BigQuery, Snowflake, Redshift 등
    • 린팅과 포매팅: 코드 스타일 검사와 자동 포매팅 기능
    • 설정 가능: 프로젝트별 커스텀 룰과 스타일 설정
    • CI/CD 통합: GitHub Actions, GitLab CI 등과 쉬운 연동
    • 플러그인 시스템: 확장 가능한 아키텍처

    왜 SQLFluff를 사용하는가?

    1. 코드 포맷 일관성 유지

    -- Before
    select col1,col2 from table1 where col1='value'
    
    -- After (SQLFluff 적용 후)
    SELECT
        col1,
        col2
    FROM table1
    WHERE col1 = 'value'
    

    2. 팀 협업 개선

    • 일관된 SQL 스타일 가이드 적용
    • 코드 리뷰 시 스타일 논의 최소화
    • 새로운 팀원의 빠른 적응 지원

    3. 유지보수성 증대

    • 읽기 쉬운 SQL 코드 작성
    • 버그 발생 가능성 감소
    • 코드 표준화를 통한 유지보수 용이성

    SQLFluff vs SQLfmt 비교

    기능 SQLFluff SQLfmt
    주요 목적 린팅 + 포매팅 포매팅 전문
    방언 지원 15+ 방언 지원 PostgreSQL 중심
    린팅 규칙 100+ 규칙 제공 제한적
    설정 옵션 매우 세밀한 설정 간단한 설정
    성능 상대적으로 느림 매우 빠름
    학습 곡선 높음 낮음
    커뮤니티 활발한 개발 소규모

    상세 비교

    SQLFluff의 장점

    • 종합적인 분석: 포매팅뿐만 아니라 잠재적 버그, 성능 이슈 탐지
    • 광범위한 방언 지원: 다양한 데이터베이스 환경에서 사용 가능
    • 풍부한 규칙: L001~L067까지 다양한 린팅 규칙 제공
    • 커스터마이징: 프로젝트 요구사항에 맞는 세밀한 설정

    SQLfmt의 장점

    • 속도: 매우 빠른 포매팅 처리
    • 단순함: 최소한의 설정으로 즉시 사용 가능
    • 안정성: 예측 가능한 포매팅 결과

    SQLFluff 설치 및 기본 사용법

    설치

    # pip를 통한 설치
    pip install sqlfluff
    
    # 특정 방언 지원을 위한 설치
    pip install sqlfluff[postgres]
    pip install sqlfluff[bigquery]
    pip install sqlfluff[all]  # 모든 방언 지원
    

    기본 사용법

    1. 린팅 (문제점 검사)

    # 단일 파일 린팅
    sqlfluff lint my_query.sql
    
    # 디렉토리 전체 린팅
    sqlfluff lint sql/
    
    # 특정 방언으로 린팅
    sqlfluff lint --dialect postgres my_query.sql

    2. 포매팅

    # 파일 포매팅 (변경사항 미리보기)
    sqlfluff format my_query.sql
    
    # 실제 파일 수정
    sqlfluff format --write-file my_query.sql
    
    # 디렉토리 전체 포매팅
    sqlfluff format --write-file sql/

    3. 자동 수정

    # 자동 수정 가능한 문제들 해결
    sqlfluff fix my_query.sql
    
    # 실제 파일에 적용
    sqlfluff fix --write-file my_query.sql

    설정 파일 (.sqlfluff)

    기본 설정 예시

    [sqlfluff]
    dialect = postgres
    templater = jinja
    exclude_rules = L003,L014
    
    [sqlfluff:indentation]
    indented_joins = true
    indented_ctes = true
    indented_using_on = true
    
    [sqlfluff:rules:L010]
    capitalisation_policy = upper
    
    [sqlfluff:rules:L030]
    extended_capitalisation_policy = upper

    주요 설정 옵션

    기본 설정

    • dialect: 사용할 SQL 방언 (postgres, mysql, bigquery 등)
    • exclude_rules: 제외할 규칙 목록
    • max_line_length: 최대 줄 길이 (기본: 80)

    들여쓰기 설정

    • indented_joins: JOIN 절 들여쓰기 여부
    • indented_ctes: CTE 들여쓰기 여부
    • tab_space_size: 탭 크기 설정

    주요 린팅 규칙

    스타일 관련 규칙

    • L001: 불필요한 후행 공백
    • L003: 들여쓰기가 탭과 공백으로 혼재
    • L010: 대소문자 일관성
    • L014: 식별자 인용 일관성

    구조 관련 규칙

    • L019: 쉼표 위치 (후행 쉼표 vs 선행 쉼표)
    • L025: 별칭에서 AS 키워드 사용
    • L036: SELECT 절에서 불필요한 공백

    성능 관련 규칙

    • L042: JOIN 조건에서 서로 다른 테이블 참조
    • L044: 쿼리에서 COUNT(*)보다 COUNT(1) 선호

    실제 사용 예시

    Before (원본 코드)

    select u.name,u.email,count(o.id) as order_count from users u left join orders o on u.id=o.user_id where u.active=true group by u.id,u.name,u.email having count(o.id)>5

    After (SQLFluff 포매팅 후)

    SELECT
        u.name,
        u.email,
        COUNT(o.id) AS order_count
    FROM users AS u
    LEFT JOIN orders AS o
        ON u.id = o.user_id
    WHERE u.active = TRUE
    GROUP BY
        u.id,
        u.name,
        u.email
    HAVING COUNT(o.id) > 5

    설정 방법

    1. pyproject.toml을 통한 설정

    [tool.sqlfluff.core]
    dialect = "postgres"
    exclude_rules = ["L003", "L014"]
    
    # pre-commit 설정
    [tool.sqlfluff.rules.L003]
    lint_templated_tokens = false
    

    2. pre-commit hooks 설정

    .pre-commit-config.yaml

    repos:
      - repo: https://github.com/sqlfluff/sqlfluff
        rev: 2.3.5
        hooks:
          - id: sqlfluff-lint
            # additional_dependencies: ['<dbt-adapter>', 'sqlfluff-templater-dbt']
          - id: sqlfluff-fix
            # additional_dependencies: ['<dbt-adapter>', 'sqlfluff-templater-dbt']
    

    주요 설정 옵션 상세 설명

    [tool.sqlfluff.core] 섹션

    • dialect: 사용할 SQL 방언 (postgres, mysql, bigquery, snowflake 등)
    • templater: 템플릿 엔진 (none, jinja, python, dbt)
    • exclude_rules: 제외할 규칙 목록 (["L003", "L014"] 형태)
    • max_line_length: 최대 줄 길이 (기본: 80)
    • large_file_skip_byte_limit: 큰 파일 스킵 기준 (바이트)

    [tool.sqlfluff.indentation] 섹션

    • indented_joins: JOIN 절 들여쓰기 여부
    • indented_ctes: CTE 들여쓰기 여부
    • indented_using_on: ON/USING 절 들여쓰기
    • tab_space_size: 탭 크기 설정 (기본: 4)
    • allow_implicit_indents: 암시적 들여쓰기 허용

    [tool.sqlfluff.capitalisation] 섹션

    • keywords: SQL 키워드 대소문자 ("upper", "lower", "capitalise")
    • identifiers: 식별자 대소문자
    • functions: 함수명 대소문자
    • literals: 리터럴 대소문자# SQLFluff 완벽 가이드

    어떤 도구를 선택할 것인가?

    SQLFluff를 선택해야 하는 경우

    1. 복잡한 프로젝트: 다양한 SQL 방언 사용
    2. 팀 프로젝트: 일관된 코드 품질 관리 필요
    3. 엔터프라이즈 환경: 세밀한 규칙 설정과 거버넌스 필요
    4. 코드 품질 중시: 포매팅 이상의 린팅 기능 필요

    SQLfmt를 선택해야 하는 경우

    1. 단순한 요구사항: 기본적인 포매팅만 필요
    2. 성능 중시: 빠른 처리 속도 필요
    3. PostgreSQL 환경: PostgreSQL만 사용하는 환경
    4. 간단한 설정: 복잡한 설정 없이 즉시 사용

    권장 사항

    대부분의 경우 SQLFluff 권장

    • 초기 설정이 복잡해도 장기적으로 더 큰 이익
    • 다양한 방언 지원으로 확장성 확보
    • 활발한 커뮤니티와 지속적인 업데이트
    • CI/CD 통합의 용이성

    하이브리드 접근

    일부 팀에서는 두 도구를 함께 사용하기도 합니다:

    • 개발 중: SQLfmt로 빠른 포매팅
    • CI/CD: SQLFluff로 종합적인 품질 검사

    sqlfluff 고급 사항

    1. sqlfluff fix . 를 해도 파일이 아무런 변경이 없는 경우

    sqlfluff의 작업 흐름은 크게 세 단계로 이루어집니다.

    1. Templating: SQL 파일 내의 변수나 매크로를 실제 값으로 변환
    2. Parsing: 변환된 SQL 코드를 sqlfluff가 이해할 수 있는 구문 트리로 분석
    3. Linting: 구문 트리를 기반으로 aliasing.table과 같은 규칙을 적용하여 스타일 위반을 찾음

    fix 명령어는 코드를 수정하기 전에 반드시 parsing 단계가 성공해야 합니다. 파싱 오류가 발생하면 sqlfluff는 안전을 위해 더 이상 진행하지 않고 작업을 중단하도록 설계되어 있습니다. 이는 sqlfluff가 코드를 잘못 이해한 상태에서 수정을 시도하여 의도치 않은 손상을 입히는 것을 방지하기 위한 중요한 안전장치입니다.

    즉, sqlfluff parsing과 실제 sql이 실행되는지 진행하여 문제를 사전에 확인한 다음, sqlfluff fix를 진행해야 합니다.

    sql lint . 시 아래와 같이 PRS가 발생했으면 파싱 오류로 fix 명령어가 실행되지 않습니다.

    L:   9 | P:   1 |  PRS | Line 9, Position 1: Found unparsable section: 'SELECT\n 
                           | a,\n    b\nFROM\n    2020.foo,\n ...'

    2. pyproject.toml에 옵션 설정 방법

    rules = ["LO01"] 과 같은 형식은 sqlfluff 버전이 낮을 때만 적용되고 최신 버전에선 허용하지 않는 패턴입니다. https://docs.sqlfluff.com/en/stable/reference/rules.html#rule-aliasing.table 의 문서에 나와있는 것처럼 tool.sqlfluff.rules.xxxxx 형태로 입력해야 합니다.

    3. 실제 운영에서 사용할 수 있는 옵션

    [tool.sqlfluff.core]
    dialect = "databricks"
    templater = "jinja"
    max_line_length = 88
    exclude_rules =""
    sql_file_exts = ".sql,.SQL"
    
    [tool.sqlfluff.rules.aliasing.table]
    # AS 키워드 필수
    aliasing = "explicit"
    [tool.sqlfluff.rules.aliasing.column]
    # 컬럼 별칭도 AS 필수
    aliasing = "explicit"
    [tool.sqlfluff.rules.aliasing.expression]
    # 표현식 별칭에서 AS 키워드 강제 사용
    # "explicit": SELECT COUNT(*) AS total_count
    allow_scalar=true
    
    [tool.sqlfluff.rules.capitalisation.identifiers]
    # 테이블명, 컬럼명 등 식별자 소문자 강제
    # 현대적 스타일과 타이핑 편의성
    capitalisation_policy = "lower"
    [tool.sqlfluff.rules.capitalisation.functions]
    # 함수명 대문자 강제 (COUNT, SUM, AVG 등)
    # SQL 키워드와 일관성 유지
    extended_capitalisation_policy = "upper"
    [tool.sqlfluff.rules.capitalisation.literals]
    # 리터럴 값 소문자 강제 (true, false, null 등)
    # 현대적 스타일 적용
    capitalisation_policy = "lower"
    [tool.sqlfluff.rules.capitalisation.keywords]
    # SQL 키워드 대문자 강제 (SELECT, FROM, WHERE 등)
    # 가독성과 전통적인 SQL 스타일 유지
    capitalisation_policy = "upper"
    
    [tool.sqlfluff.rules.layout.commas]
    # 쉼표 스타일 - 후행 쉼표 사용 (가독성과 diff 친화적)
    line_position = "trailing"
    
    [tool.sqlfluff.rules.convention.select_trailing_comma]
    # SELECT 절 후행 쉼표 정책
    select_clause_trailing_comma = "forbid"
    [tool.sqlfluff.rules.convention.count_rows]
    # 성능과 명확성을 위해 COUNT(*) 권장
    prefer_count_1 = false
    [tool.sqlfluff.rules.convention.not_equal]
    # !=, <> 섞어 사용하지 않고 !=만 쓰도록
    preferred_not_equal_style = "c_style"
    
    [tool.sqlfluff.indentation]
    # JOIN 절 들여쓰기 (쿼리 구조 명확화)
    indented_joins = true
    # CTE (WITH 절) 들여쓰기
    indented_ctes = true
    # ON/USING 절 들여쓰기
    indented_using_on = true
    # ON 절 내용 추가 들여쓰기
    indented_on_contents = true
    # CASE WHEN 절 들여쓰기
    indented_cases = true
    # 탭 크기 (일관된 들여쓰기)
    tab_space_size = 4
    # 암시적 들여쓰기 허용 안함 (명시적 구조 강제)
    allow_implicit_indents = false
    
    [tool.sqlfluff.templater]
    # 템플릿 블록 들여쓰기
    unwrap_wrapped_queries = true

    결론

    SQLFluff는 SQL 코드의 품질과 일관성을 크게 향상시킬 수 있는 강력한 도구입니다. 초기 설정과 학습에 시간이 필요하지만, 장기적으로 팀의 생산성과 코드 품질을 크게 개선할 수 있습니다.

    레퍼런스

    https://docs.sqlfluff.com/en/stable/reference/rules.html#rule-aliasing.table

    댓글