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 순서로 정리했습니다.
한눈에 요약
- 네이티브 데이터 테이블
- n8n 내부에 구조화 테이블을 영구 저장하고 Data table 노드로 CRUD/Upsert/조건 삭제(Dry Run 포함)까지 수행합니다.
- 기본 용량 50MB(Cloud/무료 기준). Self-hosted는 환경변수로 상향 가능합니다.
- 상태·룩업·경량 참조에 최적. 고부하/관계형 제약이 필요한 경우 외부 DB 권장.
- Python Task Runner (Native, Beta)
- Pyodide 기반을 대체하는 네이티브 파이썬 샌드박스. Self-hosted는 실제 파이썬 모듈(import) 사용 가능(허용목록 기반).
- Cloud는 점진 전환(일부 인스턴스만 사용 가능)이며 임포트 제한이 있을 수 있습니다.
- 브레이킹 변경: Code 노드의
python
스크립트는pythonNative
로 전환 및 문법 보정 필요.
네이티브 데이터 테이블
1) 설계 의도
- 외부 DB/문서 스프레드시트 없이 워크플로우 가까운 곳에 경량 데이터 저장소를 두어 속도·보안·운영 편의를 확보하려는 목적입니다.
- 프로젝트 범위 스코프로 관리되며, 복잡한 조인/트랜잭션/제약조건보다는 간단한 상태·매핑·참조 처리에 초점을 맞습니다.
2) 주요 기능
- CRUD & Upsert: 기본 삽입/조회/수정/삭제 + 중복키 기반 Upsert
- 조건 삭제 + Dry Run: 삭제 조건으로 시뮬레이션 먼저 수행 후 실제 삭제
- 조건 조회: 단일/복수 필드 조건, Limit/정렬 옵션(노드 옵션 기준)
- 스키마 관리: 기본키/유니크 키에 준하는 고유 식별 필드 설계 가능(노드/테이블 생성 시 정의)
3) 생성·사용 절차 (권장 핸즈온 흐름)
- 테이블 생성: 편집기 캔버스에서 Create data table → 테이블 이름, 컬럼(타입), 키 설정
- 노드 배치: 워크플로우에 Data table 노드 추가 → Operation 선택(Get/Insert/Update/Upsert/Delete)
- 조건 구성: 예)
email = {{$json.email}}
처럼 Expression 으로 조건 바인딩 - 반환·제한: 필요 시 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) 데이터 테이블 보안
- 데이터 분류: PII/민감정보는 원천 저장 금지. 불가피 시 토큰화/해시/암호화 적용.
- 최소 권한: 프로젝트 단위 RBAC로 편집/삭제 권한 최소화.
- 용량·보존 정책: 50MB 초과 가능성/장기 보존 요구 시 외부 DB로 오프로드(백업·복구·보존 주기 명시).
- 감사 가능성: 변경 이력(Log) 기록, 중요 테이블은 무결성 해시(예: 증분 해시체인) 병행.
2) Python Runner 격리/통제
- 외부 Runner 모드: n8n와 Runner 프로세스 격리, Runner 네임스페이스에 아웃바운드 네트워크 ACL 적용.
- 인증·암호화:
N8N_RUNNERS_AUTH_TOKEN
비밀관리(Secret Manager), Runner–Broker 트래픽 TLS 권장. - Allowlist 기반 임포트: 표준/서드파티 모듈을 필수 최소 셋으로만 허용.
- 자원 제한: 오토 셧다운/시간제한/메모리 제한으로 DoS 방지.
- Cloud 주의: 임포트 제한으로 공격면 축소. 전환 시 스크립트 호환성 점검 필수.
3) 운영 통제
- 위험 노드 차단: Execute Command 등 고위험 노드 사용 사전 승인/정책 적용.
- 로그 중앙집중화: Runner/워크플로우 실패·시간초과·재시도 이벤트를 SIEM/EDR/알림으로 통합.
- 서드파티 검증: 라이브러리 서명·무결성 확인, 취약점 스캔(OSV/Dependabot/Trivy) 정기화.
마이그레이션 플레이북
A) Pyodide → Python(Native)
- 전수 식별: Code 노드 중 언어가
python
인 항목 추출 - 파라미터 전환:
pythonNative
로 변경 - 문법 수정:
items/item
→_items/_item
,dot
→bracket
- 모듈 의존성 처리: runners 이미지에
extras.txt
+ allowlist 반영 후 배포 - 테스트: Dev/Staging에서 실데이터 샘플로 성능/오류/메모리 검증 → 릴리스
- 롤백 계획: 문제 시 Pyodide 스냅샷/브랜치로 즉시 복귀
B) 외부 DB/Sheets → 데이터 테이블
- 스키마 설계: 고유키·인덱스 후보 정의(중복 방지 기준)
- 초기 적재: 일괄 Import → Upsert 전략으로 동기화
- 워크플로우 전환: 조회/상태 쓰기 경로를 Data table 노드로 교체
- 오프로드 전략: 상한(용량/성능) 도달 시 외부 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
운영 체크리스트
- 설정
-
N8N_DATA_TABLES_MAX_SIZE_BYTES
업무 특성 맞게 설정 - Runner 외부 모드, 인증 토큰/네트워크 분리/TLS 적용
- Allowlist 최소화, 모듈 버전 핀 고정, SBOM 생성
- 권한/데이터
- 프로젝트 RBAC 최소 권한, 테이블별 삭제/수정 권한 분리
- PII/민감정보 저장 금지 또는 토큰화/암호화
- 백업·보존·아카이브 정책 문서화
- 모니터링/감사
- 실행 시간/메모리/오류율 대시보드
- 실패 알림(재시도 임계치 초과) & 런너 로그 수집
- 분기별 취약점 스캔/라이브러리 업데이트 윈도우 확보
트러블슈팅 가이드
- Data table 용량 초과: 쓰기 실패/성능 저하 → 용량 상향(자체 호스팅) 또는 아카이브/외부 DB 오프로드
- Upsert 충돌: 키 컬럼 불일치/Null → 스키마/조건식 검증, 키 정규화
- Python 임포트 실패: Cloud 전환/허용목록 미설정 → Self-hosted는 allowlist/빌드 확인, Cloud는 임포트 불가를 전제로 리팩터
- Dot 접근 오류:
item.json.x
→item["json"]["x"]
로 수정 - 버전 불일치 오류: n8n ↔ runners 이미지 버전/토큰/브로커 URI 확인
자주 묻는 질문(FAQ)
Q1. 데이터 테이블을 영구 저장소로 써도 되나요?
- 경량 상태/룩업엔 좋지만, 대용량·복잡 쿼리·관계형 제약엔 외부 DB가 적합합니다.
Q2. Cloud에서도 파이썬 임포트가 가능한가요?
- 점진 전환 중이며 인스턴스에 따라 임포트 제한될 수 있습니다. 보편적으로 Self-hosted에서 완전한 임포트를 사용합니다.
Q3. Pyodide 스크립트를 그대로 돌릴 수 있나요?
- 불가합니다.
pythonNative
전환과 문법 보정(아이템 변수·bracket 접근) 이 필요합니다.
Q4. 보안팀 관점 핵심은 무엇인가요?
- 격리(외부 Runner), 최소 모듈 허용, 비밀/통신 보호, 로그·감사·취약점 관리입니다.
선택 가이드 (의사결정 트리)
- 룩업·상태·소규모 참조 → 데이터 테이블
- 고급 전처리/집계/ML 호출 → Python(Native) + (필요시) 외부 DB
- 대량 트랜잭션/관계형 제약 → 외부 DB 유지
적용 로드맵(권장)
- PoC: Python(Native) 헬로월드 + Data table Upsert
- 정책화: 보안/모듈 허용목록/RBAC/용량 기준 수립
- 점진 전환: 저위험 워크플로우부터 Pyodide→Native, Sheets/DB→Data table
- 관측성 강화: 실패 알림·지표·로그 대시보드
- 정기 점검: 분기별 라이브러리 업데이트/취약점 스캔/성능 재평가
728x90
그리드형(광고전용)
댓글