무엇을 만들어 주나?
스프레드시트를 데이터베이스에 넣으려면 대개 INSERT 문을 쓰게 되는데, 손으로 쓰는 그 자리에서 사고가 난다. 성에 든 아포스트로피가 문자열을 일찍 끝내고, 빈 칸이 NULL 이 아니라 두 글자짜리 '' 가 되고, "first name" 같은 열 이름은 유효한 식별자가 아니다.
이 생성기는 CSV 를 읽어 헤더 줄에서 열 이름을 가져오고 문장을 써 준다. 값은 따옴표를 두 번 쓰는 방식으로 이스케이프한다 — SQL 표준이 정한 형태이고 어느 데이터베이스나 받는다. MySQL 기본 모드에서만 통하는 백슬래시 방식과 다르다.
A <character string literal> that contains a quote symbol represents that symbol by two consecutive quote symbols.
기능
- 표준 따옴표 이스케이프
- 아포스트로피가 든 값은 따옴표를 두 번 써서 이스케이프한다. SQL 표준이다. 백슬래시는 MySQL 의 기본 설정일 뿐 이식 가능한 규칙이 아니고, 같은 스크립트를 PostgreSQL 에 돌리는 순간 깨진다.
- 빈 칸은 NULL 이 된다
- CSV 는 빈 문자열과 값 없음을 구분하지 못한다. 내보내기 파일에서 빈 칸은 거의 언제나 값 없음이고, 값이 없는 행을 찾는 쿼리가 실제로 찾아내는 것은 NULL 뿐이다.
- 식별자를 안전하게
- "first name" 이나 "금액 (원)" 같은 열 이름은 따옴표 없이 쓸 수 있는 식별자가 아니다. 공백과 기호를 밑줄로 바꿔 문장이 파싱되게 한다.
- 한 문장이냐 행마다냐
- 여러 행을 한 INSERT 로 묶으면 훨씬 빠르지만 한 행이 잘못되면 전부 롤백된다. 나누면 느린 대신 나머지는 들어간다. 시드를 심는 중인지 데이터를 고치는 중인지에 따라 답이 다르다.
- 타입은 선택
- 타입을 켜면 숫자와 불리언이 따옴표 없이 나가 숫자·불리언 컬럼에 그대로 들어간다. 모든 열이 텍스트이고 예상 밖의 일이 없기를 바라면 끈다.
사용법
- 1
CSV 를 붙여넣는다
헤더 줄을 포함한다 — 열 이름이 거기서 나온다.
- 2
테이블 이름을 적는다
넣을 테이블 이름을 입력한다. 식별자로 쓸 수 없는 문자는 바뀐다.
- 3
문장 모양을 고른다
시드를 심는 중이면 속도를 보고 한 문장으로, 값 하나가 나머지를 끌고 가면 안 되면 행마다 한 문장으로.
- 4
돌리기 전에 읽는다
출력을 — 특히 첫 행과 마지막 행을 — 읽고, 되돌릴 수 있는 트랜잭션 안에서 실행한다.
자주 묻는 질문
값에 든 아포스트로피는 어떻게 처리되나?
두 번 쓴다. O'Hara 는 'O''Hara' 가 된다. SQL 표준이 정한 이스케이프이고 어디서나 통한다. 백슬래시 방식은 MySQL 기본 설정에서만 동작하고 PostgreSQL 이나 표준 모드 MySQL 에서는 실패한다.
빈 칸이 왜 빈 문자열이 아니라 NULL 인가?
내보내기 파일에서 빈 칸은 거의 언제나 "값 없음"을 뜻하고, 값이 없는 행을 찾는 쿼리가 찾아내는 것은 NULL 뿐이기 때문이다 — 빈 문자열은 값이라서 IS NULL 에 걸리지 않는다. 스키마가 정말 빈 문자열을 담는다면 타입을 끄고 출력을 손본다.
한 문장과 행마다 중 어느 쪽이 맞나?
한 문장은 데이터베이스가 한 번만 계획하고 커밋해서 훨씬 빠르다 — 테스트 DB 에 시드를 심을 때 원하는 것이다. 행마다 나누면 느린 대신 값 하나가 깨져도 나머지가 들어간다 — 운영 데이터를 고칠 때 원하는 것이다.
SQL 인젝션을 막아 주나?
직접 붙여넣은 값의 따옴표를 제대로 이스케이프해 준다. 돌리기 전에 읽어 볼 일회성 스크립트에는 충분하다. 애플리케이션 코드의 파라미터 바인딩을 대신하지는 않는다 — 거기서는 값을 SQL 에 이어 붙이는 것 자체를 하지 않는다.
어느 데이터베이스용인가?
여기 쓰는 문법 — INSERT INTO 테이블 (열) VALUES (...) 와 두 번 쓴 따옴표 — 은 표준 SQL 이고 PostgreSQL·MySQL·SQLite·SQL Server 에서 돈다. 날짜와 JSON 컬럼의 타입 처리는 제품마다 다르므로 그 열은 돌리기 전에 확인한다.
데이터가 업로드되나?
아니다. 생성이 브라우저에서 일어난다. 데이터베이스로 갈 CSV 에는 대개 진짜 레코드가 들어 있어서 여기서 이 점이 중요하다.
이 도구가 따르는 규격
- PostgreSQL — 어휘 구조: 문자열 상수 — 출력이 쓰는 표준 이스케이프, 그리고 백슬래시가 이식되지 않는 이유.
- PostgreSQL — INSERT — 여러 행 VALUES 문법과 트랜잭션 동작.
- RFC 4180 — CSV — 문장을 쓰기 전에 입력을 읽는 방식.