본문 바로가기
프로그램 (PHP,Python)

외부 DB 없이 n8n 인하우스 데이터 전략: Python Task Runner(Native)

by 날으는물고기 2025. 10. 1.

외부 DB 없이 n8n 인하우스 데이터 전략: Python Task Runner(Native)

728x90
  • 자동화의 새 표준: n8n 데이터 테이블 + Python(Native)로 워크플로우 재설계
  • Pyodide→Native 한 방에: n8n 코드 노드 문법 전환 & 호환성 가이드
  • 데이터 핸들링 업그레이드: n8n 테이블 기반 중복방지·체크포인트 설계

네이티브 데이터 테이블 & Python Task Runner(Native, Beta)

9월 30일(화) 기준 최신 릴리스 노트에 따르면, 데이터 테이블은 v1.113.1(2025-09-23)에, Python Task Runner(Native, Beta)는 v1.113.2(2025-09-24)에 도입되었습니다.

아래에서 자세하게 요약 → 설계 의도 → 설치·사용 → 보안 가이드 → 운영 체크리스트 → 마이그레이션 → 트러블슈팅 → FAQ 순서로 정리했습니다.

한눈에 요약

  1. 네이티브 데이터 테이블
  • n8n 내부에 구조화 테이블을 영구 저장하고 Data table 노드CRUD/Upsert/조건 삭제(Dry Run 포함)까지 수행합니다.
  • 기본 용량 50MB(Cloud/무료 기준). Self-hosted는 환경변수로 상향 가능합니다.
  • 상태·룩업·경량 참조에 최적. 고부하/관계형 제약이 필요한 경우 외부 DB 권장.
  1. Python Task Runner (Native, Beta)
  • Pyodide 기반을 대체하는 네이티브 파이썬 샌드박스. Self-hosted는 실제 파이썬 모듈(import) 사용 가능(허용목록 기반).
  • Cloud는 점진 전환(일부 인스턴스만 사용 가능)이며 임포트 제한이 있을 수 있습니다.
  • 브레이킹 변경: Code 노드의 python 스크립트는 pythonNative 로 전환 및 문법 보정 필요.

네이티브 데이터 테이블

1) 설계 의도

  • 외부 DB/문서 스프레드시트 없이 워크플로우 가까운 곳에 경량 데이터 저장소를 두어 속도·보안·운영 편의를 확보하려는 목적입니다.
  • 프로젝트 범위 스코프로 관리되며, 복잡한 조인/트랜잭션/제약조건보다는 간단한 상태·매핑·참조 처리에 초점을 맞습니다.

2) 주요 기능

  • CRUD & Upsert: 기본 삽입/조회/수정/삭제 + 중복키 기반 Upsert
  • 조건 삭제 + Dry Run: 삭제 조건으로 시뮬레이션 먼저 수행 후 실제 삭제
  • 조건 조회: 단일/복수 필드 조건, Limit/정렬 옵션(노드 옵션 기준)
  • 스키마 관리: 기본키/유니크 키에 준하는 고유 식별 필드 설계 가능(노드/테이블 생성 시 정의)

3) 생성·사용 절차 (권장 핸즈온 흐름)

  1. 테이블 생성: 편집기 캔버스에서 Create data table → 테이블 이름, 컬럼(타입), 키 설정
  2. 노드 배치: 워크플로우에 Data table 노드 추가 → Operation 선택(Get/Insert/Update/Upsert/Delete)
  3. 조건 구성: 예) email = {{$json.email}} 처럼 Expression 으로 조건 바인딩
  4. 반환·제한: 필요 시 Limit/정렬 설정 → Downstream 노드(If/HTTP/Function 등)로 결과 전달

4) 용량·성능·한계

  • 기본 50MB(Cloud/무료). Self-hosted는 환경변수로 상향 가능
    • # 예: 200MB N8N_DATA_TABLES_MAX_SIZE_BYTES=209715200
  • 한계: 외래키·트랜잭션·고급 인덱스·뷰 등 관계형 DB 고급 기능 미지원
  • 성능 팁: 고빈도 쓰기/대용량/고복잡 조회는 외부 DB로 이관(ETL/동기화 주기 운영)

5) 대표 활용 시나리오

  • 중복 처리 방지 키 저장소: 최근 처리한 id/hash를 Upsert로 저장 → 재처리 차단
  • 코드↔라벨 매핑 테이블: 외부 API 코드 값 정규화/역매핑
  • 경량 상태 관리: 체크포인트(최근 처리 타임스탬프, 페이지 토큰 등)
  • 임시 정책·화이트리스트: 간단한 룰/옵션 테이블

Python Task Runner (Native, Beta)

1) 무엇이 달라졌나?

  • 네이티브 파이썬 런타임격리된 Runner 프로세스에서 실행 → 성능/호환성/보안 개선
  • Self-hosted: runners 이미지를 커스터마이즈해 표준 라이브러리 + 서드파티 모듈 사용(허용목록 기반)
  • Cloud: 점진 전환 중. 일부 인스턴스는 Python (Native) (Beta) 옵션이 보이며, 임포트 제한이 존재할 수 있음

2) Pyodide → Native 차이(핵심)

  • 아이템 변수명
    • (기존) items, item
    • (신규) _items, _item
  • 필드 접근 방식
    • (기존) item.json.field (dot 표기 허용)
    • (신규) item["json"]["field"] (bracket만 허용)
  • 내장 헬퍼: 기존 일부 n8n 내장 메서드/변수는 미지원 → 순수 파이썬으로 처리
  • 보안: 위험 내장 차단, 모듈 임포트는 allowlist(Self-hosted), Cloud는 임포트 제한 가능

3) 마이그레이션 예시 (Before → After)

Before (Pyodide 스타일)

for item in items:
    first = item.json.first or ""
    last  = item.json.last or ""
    item.json.full_name = (first + " " + last).strip()
return items

After (Native 파이썬)

for item in _items:
    j = item["json"]
    first = j.get("first", "") or ""
    last  = j.get("last", "") or ""
    j["full_name"] = (first + " " + last).strip()
    item["json"] = j
return _items

포인트: Code 노드의 언어 파라미터를 pythonNative로 전환하고, dot→bracket 표기 및 아이템 변수명을 수정하세요.

Self-hosted 기준: 권장 아키텍처 & 배포

1) 권장 구성 (외부 Runner 모드)

  • n8n 본체 + Task Runners 사이드카(JS/Python)
  • 버전 일치(n8n와 runners 이미지 Major/Minor 맞춤), 토큰 인증, 네트워크 경계 분리
300x250

예시 docker-compose

services:
  n8n:
    image: n8nio/n8n:1.113.2
    environment:
      - N8N_RUNNERS_ENABLED=true
      - N8N_RUNNERS_MODE=external
      - N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
      - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_TOKEN}
      - N8N_NATIVE_PYTHON_RUNNER=true
    ports: ["5678:5678"]

  task-runners:
    image: n8nio/runners:1.113.2
    environment:
      - N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
      - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_TOKEN}
      - N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT=15
    depends_on: [n8n]

2) 서드파티 모듈 추가(런너 이미지 커스텀)

  • Python 모듈 목록: extras.txt 예시
  • numpy==2.3.2 pandas==2.2.2 requests==2.32.3
  • 허용목록(allowlist) 설정: n8n-task-runners.json 예시
{
  "task-runners": [
    {
      "runner-type": "python",
      "env-overrides": {
        "PYTHONPATH": "/opt/runners/task-runner-python",
        "N8N_RUNNERS_STDLIB_ALLOW": "json,datetime,hashlib",
        "N8N_RUNNERS_EXTERNAL_ALLOW": "numpy,pandas,requests"
      }
    }
  ]
}

운영 팁: 버전 핀 고정(==)으로 재현성 확보, 빌드 아티팩트에 SBOM 생성(예: pip-licenses, cyclonedx-py 등) 권장.

보안 가이드

1) 데이터 테이블 보안

  1. 데이터 분류: PII/민감정보는 원천 저장 금지. 불가피 시 토큰화/해시/암호화 적용.
  2. 최소 권한: 프로젝트 단위 RBAC로 편집/삭제 권한 최소화.
  3. 용량·보존 정책: 50MB 초과 가능성/장기 보존 요구 시 외부 DB로 오프로드(백업·복구·보존 주기 명시).
  4. 감사 가능성: 변경 이력(Log) 기록, 중요 테이블은 무결성 해시(예: 증분 해시체인) 병행.

2) Python Runner 격리/통제

  1. 외부 Runner 모드: n8n와 Runner 프로세스 격리, Runner 네임스페이스에 아웃바운드 네트워크 ACL 적용.
  2. 인증·암호화: N8N_RUNNERS_AUTH_TOKEN 비밀관리(Secret Manager), Runner–Broker 트래픽 TLS 권장.
  3. Allowlist 기반 임포트: 표준/서드파티 모듈을 필수 최소 셋으로만 허용.
  4. 자원 제한: 오토 셧다운/시간제한/메모리 제한으로 DoS 방지.
  5. Cloud 주의: 임포트 제한으로 공격면 축소. 전환 시 스크립트 호환성 점검 필수.

3) 운영 통제

  • 위험 노드 차단: Execute Command 등 고위험 노드 사용 사전 승인/정책 적용.
  • 로그 중앙집중화: Runner/워크플로우 실패·시간초과·재시도 이벤트를 SIEM/EDR/알림으로 통합.
  • 서드파티 검증: 라이브러리 서명·무결성 확인, 취약점 스캔(OSV/Dependabot/Trivy) 정기화.

마이그레이션 플레이북

A) Pyodide → Python(Native)

  1. 전수 식별: Code 노드 중 언어가 python 인 항목 추출
  2. 파라미터 전환: pythonNative 로 변경
  3. 문법 수정: items/item_items/_item, dotbracket
  4. 모듈 의존성 처리: runners 이미지에 extras.txt + allowlist 반영 후 배포
  5. 테스트: Dev/Staging에서 실데이터 샘플로 성능/오류/메모리 검증 → 릴리스
  6. 롤백 계획: 문제 시 Pyodide 스냅샷/브랜치로 즉시 복귀

B) 외부 DB/Sheets → 데이터 테이블

  1. 스키마 설계: 고유키·인덱스 후보 정의(중복 방지 기준)
  2. 초기 적재: 일괄 Import → Upsert 전략으로 동기화
  3. 워크플로우 전환: 조회/상태 쓰기 경로를 Data table 노드로 교체
  4. 오프로드 전략: 상한(용량/성능) 도달 시 외부 DB로 자동 덤프/아카이브

실전 스니펫·패턴

1) Python(Native) 런타임 확인

# Code 노드: Python (Native) (Beta)
for item in _items:
    j = item["json"]
    j["runner"] = "python-native-ok"
    item["json"] = j
return _items

2) Data table Upsert (중복 방지 키)

  • Operation: Upsert
  • 조건: email = {{$json.email}}
  • 필드 매핑: name, status, updated_at = {{$now}}
  • 활용: 중복 방지/최신 상태 유지(삭제 전 Dry Run으로 시뮬레이션)

3) 경량 집계(자체 호스팅, pandas 예)

# extras.txt에 pandas 허용 + allowlist 반영된 상태 가정
import pandas as pd

rows = [i["json"] for i in _items]
df = pd.DataFrame(rows)
top = df.groupby("category")["amount"].sum().reset_index().sort_values("amount", ascending=False)
out = []
for _, r in top.iterrows():
    out.append({"json": {"category": r["category"], "total": float(r["amount"])}})
return out

운영 체크리스트

  1. 설정
  • N8N_DATA_TABLES_MAX_SIZE_BYTES 업무 특성 맞게 설정
  • Runner 외부 모드, 인증 토큰/네트워크 분리/TLS 적용
  • Allowlist 최소화, 모듈 버전 핀 고정, SBOM 생성
  1. 권한/데이터
  • 프로젝트 RBAC 최소 권한, 테이블별 삭제/수정 권한 분리
  • PII/민감정보 저장 금지 또는 토큰화/암호화
  • 백업·보존·아카이브 정책 문서화
  1. 모니터링/감사
  • 실행 시간/메모리/오류율 대시보드
  • 실패 알림(재시도 임계치 초과) & 런너 로그 수집
  • 분기별 취약점 스캔/라이브러리 업데이트 윈도우 확보

트러블슈팅 가이드

  • Data table 용량 초과: 쓰기 실패/성능 저하 → 용량 상향(자체 호스팅) 또는 아카이브/외부 DB 오프로드
  • Upsert 충돌: 키 컬럼 불일치/Null → 스키마/조건식 검증, 키 정규화
  • Python 임포트 실패: Cloud 전환/허용목록 미설정 → Self-hosted는 allowlist/빌드 확인, Cloud는 임포트 불가를 전제로 리팩터
  • Dot 접근 오류: item.json.xitem["json"]["x"] 로 수정
  • 버전 불일치 오류: n8n ↔ runners 이미지 버전/토큰/브로커 URI 확인

자주 묻는 질문(FAQ)

Q1. 데이터 테이블을 영구 저장소로 써도 되나요?

  • 경량 상태/룩업엔 좋지만, 대용량·복잡 쿼리·관계형 제약엔 외부 DB가 적합합니다.

Q2. Cloud에서도 파이썬 임포트가 가능한가요?

  • 점진 전환 중이며 인스턴스에 따라 임포트 제한될 수 있습니다. 보편적으로 Self-hosted에서 완전한 임포트를 사용합니다.

Q3. Pyodide 스크립트를 그대로 돌릴 수 있나요?

  • 불가합니다. pythonNative 전환과 문법 보정(아이템 변수·bracket 접근) 이 필요합니다.

Q4. 보안팀 관점 핵심은 무엇인가요?

  • 격리(외부 Runner), 최소 모듈 허용, 비밀/통신 보호, 로그·감사·취약점 관리입니다.

선택 가이드 (의사결정 트리)

  • 룩업·상태·소규모 참조데이터 테이블
  • 고급 전처리/집계/ML 호출Python(Native) + (필요시) 외부 DB
  • 대량 트랜잭션/관계형 제약외부 DB 유지

적용 로드맵(권장)

  1. PoC: Python(Native) 헬로월드 + Data table Upsert
  2. 정책화: 보안/모듈 허용목록/RBAC/용량 기준 수립
  3. 점진 전환: 저위험 워크플로우부터 Pyodide→Native, Sheets/DB→Data table
  4. 관측성 강화: 실패 알림·지표·로그 대시보드
  5. 정기 점검: 분기별 라이브러리 업데이트/취약점 스캔/성능 재평가
728x90
그리드형(광고전용)

댓글