PostgreSQL / MySQL 노드 — 데이터베이스 자동화

PostgreSQL / MySQL 노드 — 데이터베이스 자동화

데이터베이스는 모든 시스템의 심장이다. n8n에서 직접 DB에 쿼리를 날리면 중간 API 없이도 데이터를 자유자재로 다룰 수 있다.

DB Credential 설정

PostgreSQL

Host: db.example.com
Port: 5432
Database: myapp
User: n8n_readonly
Password: ********
SSL: ON (권장)

MySQL

Host: db.example.com
Port: 3306
Database: myapp
User: n8n_readonly
Password: ********

🔒 보안 원칙: n8n 전용 DB 사용자를 만들고 필요한 최소 권한만 부여하자. 프로덕션 DB에 root 권한으로 접근하는 것은 위험하다.

-- PostgreSQL: 읽기 전용 사용자 생성
CREATE USER n8n_readonly WITH PASSWORD 'secure_password';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO n8n_readonly;

-- 쓰기도 필요하면
CREATE USER n8n_worker WITH PASSWORD 'secure_password';
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO n8n_worker;

기본 CRUD 동작

SELECT — 데이터 조회

Operation: Execute Query
Query:
  SELECT id, name, email, created_at
  FROM users
  WHERE status = 'active'
  ORDER BY created_at DESC
  LIMIT 100

결과가 n8n 아이템으로 변환된다:

[
  { "id": 1, "name": "홍길동", "email": "hong@...", "created_at": "2026-04-01" },
  { "id": 2, "name": "김철수", "email": "kim@...", "created_at": "2026-03-15" }
]

INSERT — 데이터 입력

Operation: Insert
Table: orders
Columns:
  customer_id: {{ $json.customerId }}
  product: {{ $json.productName }}
  amount: {{ $json.price }}
  created_at: {{ $now.toISO() }}

UPDATE — 데이터 수정

Operation: Update
Table: orders
Set:
  status: "shipped"
  shipped_at: {{ $now.toISO() }}
Where:
  id: {{ $json.orderId }}

Upsert — 있으면 수정, 없으면 삽입

Operation: Upsert
Table: products
Columns: id, name, price, updated_at
Conflict Column: id

기존에 같은 id가 있으면 UPDATE, 없으면 INSERT. 동기화 작업에 필수.


파라미터 바인딩 — SQL 인젝션 방지

절대로 사용자 입력을 SQL에 직접 넣지 말자.

-- ❌ 위험: SQL 인젝션 가능
SELECT * FROM users WHERE email = '{{ $json.email }}'

-- ✅ 안전: 파라미터 바인딩 사용
SELECT * FROM users WHERE email = $1

n8n의 Query Parameters에 $json.email 값을 바인딩하면 된다.


실전: 외부 API → DB 동기화

[Schedule: 매시간] → [HTTP: 외부 API] → [Split In Batches: 50개]
  → [PostgreSQL: Upsert] → [Loop] → [Slack: 동기화 완료 알림]

Code 노드로 변환 후 Upsert

const items = $input.all();
return items.map(item => ({
  json: {
    id: item.json.externalId,
    name: item.json.fullName,
    email: item.json.contactEmail,
    synced_at: new Date().toISOString()
  }
}));

SSH 터널 접속

프라이빗 네트워크 안의 DB에 접근해야 할 때:

SSH Host: bastion.example.com
SSH Port: 22
SSH User: deploy
SSH Private Key: (키 내용)
DB Host: 10.0.1.50 (내부 IP)
DB Port: 5432

📝 정리

  • [x] DB Credential: 전용 사용자 생성, 최소 권한 원칙
  • [x] CRUD: SELECT(조회), INSERT(입력), UPDATE(수정), Upsert(동기화)
  • [x] SQL 인젝션 방지: 파라미터 바인딩($1, $2) 필수
  • [x] 실전: 외부 API 데이터 → DB Upsert 동기화 파이프라인

다음 편 예고

18편: GitHub / GitLab 노드 — 개발자 워크플로우 자동화

PR 알림, 이슈 자동 라벨링, 릴리스 노트 생성까지. 개발 팀의 반복 업무를 n8n이 대신한다.