DuckDB in Action·Manning, 2024· 제2장 정독
2 GETTING STARTED WITH DUCKDB
원서 12–21쪽

실행 파일 하나를 복사하는 것으로 끝나는 설치

제1장이 DuckDB의 됨됨이를 논했다면, 제2장은 손을 쓴다. 무대는 명령행 인터페이스(CLI) 하나로 좁혀진다. 서버를 세우지 않고, 설치 프로그램도 라이브러리도 없이, duckdb라는 이름의 바이너리 한 개를 제자리에 두는 것으로 준비가 끝난다. 그다음은 점(.) 하나로 시작하는 명령들과 확장 체계를 익히고, 마지막에는 인터넷 저편의 CSV 파일을 내려받지 않은 채로 질의한다.

이 장이 다루는 것
DuckDB CLI의 설치와 사용법, CLI에서의 명령 실행, 원격 파일 질의
절 구성
2.1 – 2.5 (하위 절 2.2.1 – 2.2.2, 2.3.1 – 2.3.3, 2.5.1) 및 요약
실린 것
목록 7건 · 표 1건 · 사이드바 1건 · 도판 없음
기준 판본
DuckDB v0.10.0 (집필 시점)
zsh — duckdb 첫 실행
$ duckdb
v0.10.0 20b1486d11
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
D 
네 줄이 전부다. 접속 문자열도, 포트도, 자격 증명도 없다. 다만 transient라는 낱말은 눈여겨봐야 한다. 이 데이터베이스는 일시적이며 모든 데이터를 메모리에 들고 있다가, CLI를 나가는 순간 사라진다. 나가는 방법은 .quit 또는 .exit.

DuckDB가 무엇이며 어째서 2020년대 초에 이름을 얻게 되었는지를 알았으니, 이제 친해질 차례다. 저자들이 이 장의 무대를 명령행 인터페이스 하나로 좁힌 이유는 분명하다. 가장 빠르게 속도를 낼 수 있는 길이라고 보았기 때문이다. 여러 환경에 설치하는 법을 익히고, 내장 명령들을 배우고, 원격 CSV 파일을 질의하는 것으로 장을 맺는다.

순서만 놓고 보면 흔한 입문 장이다. 그러나 읽어가다 보면 이 장이 실은 하나의 주장을 반복해서 증명하고 있음을 알게 된다. DuckDB를 쓰기 위해 준비해야 할 것이 거의 없다는 주장이다. 설치에 바이너리 하나, 실행에 명령어 한 낱말, 원격 파일을 읽는 데 확장 하나. 그 절제된 목록이 이 장의 성격이다.

2.1

지원하는 환경Supported environments

DuckDB는 여러 프로그래밍 언어와 운영체제에서 쓸 수 있다. 리눅스, 윈도, macOS를 모두 지원하며, Intel/AMD와 ARM 아키텍처 양쪽을 아우른다. 집필 시점을 기준으로 지원 목록은 다음과 같다.

명령행 CLIPythonRJava JavaScriptGoRustNode.js JuliaC/C++ODBCJDBC WASMSwift

이 장은 그중 명령행만 다룬다. 독자를 가장 빨리 궤도에 올려놓는 방법이라고 저자들이 판단했기 때문이다. 여기서 제1장의 개념 하나가 실물로 확인된다. DuckDB CLI는 별도의 서버 설치를 요구하지 않는다. DuckDB가 임베디드 데이터베이스이며, CLI의 경우에는 CLI 실행 파일 자체에 임베드되어 있기 때문이다. 데이터베이스가 도구 안에 들어앉아 있는 것이다.

명령행 도구는 깃허브 릴리스로 배포된다. 운영체제와 아키텍처별로 다양한 패키지가 있고, 전체 목록은 설치 안내 페이지에서 확인할 수 있다.

2.2

CLI 설치Installing the DuckDB CLI

저자들은 이 설치를 "복사해 넣는(copy to)" 설치라고 부른다. 설치 프로그램도 필요 없고 라이브러리도 필요 없다는 뜻이다. CLI의 실체는 duckdb라는 이름의 단일 바이너리 하나다. 설치라고 부르기가 민망할 정도로 간소한데, 바로 그 간소함이 이 도구의 성격을 가장 잘 말해준다.

macOS 2.2.1

macOS에서는 Homebrew 패키지 설치 도구를 쓰라는 것이 공식 권고다.

macOS — Homebrew 목록 2.1
# Homebrew 패키지 관리자 자체를 설치할 때만 필요하다.
# 이미 갖고 있다면 이 줄은 실행하지 않는다.
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/\
Homebrew/install/HEAD/install.sh)"

$ brew install duckdb

리눅스와 윈도 2.2.2

리눅스와 윈도에는 아키텍처와 판본에 따라 여러 패키지가 준비되어 있다. 전체 목록은 깃허브 릴리스 페이지에 있다. 아래는 AMD64 아키텍처의 리눅스에서 CLI를 띄우는 절차다.

linux — amd64 목록 2.2
$ wget https://github.com/duckdb/duckdb/releases/download/v0.10.0/\
duckdb_cli-linux-amd64.zip
$ unzip duckdb_cli-linux-amd64.zip
$ ./duckdb -version
이 링크의 판본은 깃허브 릴리스 페이지의 최신 버전으로 갱신해서 쓴다. 압축을 풀면 실행 파일 하나가 나오고, 그것으로 끝이다.
2.3

CLI 사용하기Using the DuckDB CLI

CLI를 띄우는 가장 간단한 방법은 duckdb 한 낱말이다. 저자들의 표현대로, 그렇다, 이토록 짧고 이토록 빠르다. 실행하면 앞의 표제부에서 본 네 줄이 나온다. 데이터베이스는 일시적이며 모든 데이터가 메모리에 놓인다. CLI를 나가면 사라진다.

SQL 문 2.3.1

SQL 문은 명령행에 직접 입력하거나 붙여 넣고, 세미콜론과 줄바꿈으로 끝낸다. 세미콜론이 없는 동안에는 줄바꿈을 계속 넣을 수 있다. 문장은 곧바로 실행되어 결과를 압축된 표 형식으로 출력한다. 출력 형식은 2.5.1절에서 설명하는 방법으로 바꿀 수 있다. 오래 걸리는 작업에는 진행 표시줄이 나타난다.

간단한 select 문 목록 2.3
D select v.* from values (1),(3),(3),(7) as v;
col0
int32
1
3
3
7
기본값은 이 표 형식이다. 컬럼 이름 아래에 타입 한 줄이 따라붙는 것이 이 격자의 특징이며, 이 형식의 이름이 곧 duckbox다.
← 좌우로 밀어 보기 →

점 명령 2.3.2

SQL 문과 일반 명령 외에, CLI에서만 쓸 수 있는 특별한 명령이 따로 있다. 점 명령(dot command)이다. 규칙은 엄격하다. 줄을 마침표(.)로 시작하고, 곧바로 명령 이름을 붙인다. 추가 인자는 명령 뒤에 공백으로 구분해 넣는다. 점 명령은 반드시 한 줄 안에 입력해야 하고, 마침표 앞에 공백이 있어서는 안 된다. 그리고 보통의 SQL 문이나 명령과 달리 줄 끝에 세미콜론이 필요하지 않다.

널리 쓰이는 것들은 다음과 같다.

.open현재 데이터베이스 파일을 닫고 새 파일을 연다.
.readCLI 안에서 SQL 파일을 읽어 실행한다.
.tables현재 사용할 수 있는 테이블과 뷰의 목록을 보여준다.
.timer on/offSQL 실행 시간 출력을 켜고 끈다.
.mode출력 형식을 제어한다.
.maxrows기본으로 보여줄 행의 수를 제어한다(duckbox 형식에 해당).
.excel다음 명령의 출력을 스프레드시트로 보여준다.
.exit  .quit  ctrl-dCLI를 나간다.

전체 목록은 .help로 받아볼 수 있다.

CLI 인자 2.3.3

CLI는 인자를 받는다. 데이터베이스 모드를 조정하거나, 출력 형식을 제어하거나, 대화형 모드로 들어갈지 여부를 결정하는 데 쓴다. 사용법은 duckdb [OPTIONS] FILENAME [COMMANDS]다.

-readonly데이터베이스를 읽기 전용으로 연다.
-json출력 모드를 json으로 설정한다.
-line출력 모드를 line으로 설정한다.
-unsigned서명되지 않은 확장의 적재를 허용한다.
-s COMMAND
-c COMMAND
주어진 명령을 실행한 뒤 종료한다. 주어진 파일에서 입력을 읽는 .read 점 명령과 함께 쓸 때 특히 요긴하다.

다음은 질의 결과를 JSON으로 출력하도록 CLI에 매개변수를 준 예다.

비대화형 실행 — JSON 출력 2.3.3
$ duckdb --json -c 'select v.* from values (1),(3),(3),(7) as v;'

[{"col0":1},
{"col0":3},
{"col0":3},
{"col0":7}]
쓸 수 있는 인자의 목록은 duckdb -help로 얻는다.
2.4

DuckDB의 확장 체계DuckDB’s extension system

DuckDB에는 확장 체계가 있다. 데이터베이스의 핵심에 속하지 않는 기능을 여기에 담아둔다. 확장을 DuckDB와 함께 설치하는 패키지라고 생각하면 된다. 코어를 가볍게 유지하면서 필요한 사람만 필요한 것을 얹게 하는 이 설계가, 제1장에서 본 "긴 꼬리를 겨냥한다"는 말과 정확히 맞물린다.

DuckDB는 몇 가지 확장을 미리 적재한 상태로 배포되며, 그 목록은 사용하는 배포판에 따라 다르다. 설치되었든 아니든 사용할 수 있는 모든 확장의 목록은 duckdb_extensions 함수로 얻는다. 먼저 이 함수가 무슨 필드를 돌려주는지부터 확인한다.

duckdb_extensions() 출력의 형태 목록 2.4
D DESCRIBE
  SELECT *
  FROM duckdb_extensions();
column_namecolumn_type
varcharvarchar
extension_nameVARCHAR
loadedBOOLEAN
installedBOOLEAN
install_pathVARCHAR
descriptionVARCHAR
aliasesVARCHAR[]
여러 정보 가운데 요긴한 것은 확장의 이름과, 그것이 설치되어 있는지(installed), 그리고 실제로 적재되었는지(loaded)다. 설치와 적재가 별개의 상태라는 점이 이 체계의 핵심이다.
← 좌우로 밀어 보기 →

그러면 이 기계에 무엇이 설치되어 있는지 들여다본다.

설치·적재 상태 점검 2.4
D SELECT extension_name, loaded, installed
  from duckdb_extensions()
  ORDER BY installed DESC, loaded DESC;
extension_nameloadedinstalled
varcharbooleanboolean
autocompletetruetrue
ftstruetrue
icutruetrue
jsontruetrue
parquettruetrue
tpchtruetrue
httpfsfalsefalse
inetfalsefalse
jemallocfalsefalse
motherduckfalsefalse
postgres_scannerfalsefalse
spatialfalsefalse
sqlite_scannerfalsefalse
tpcdsfalsefalse
exceltrue
15 rows    3 columns
기본으로 들어와 있는 여섯 가지—autocomplete, fts, icu, json, parquet, tpch—만 참이고, 나머지는 아직 손대지 않은 상태다. 전문 검색(fts)과 국제화(icu)가 처음부터 들어 있는 것이 이 데이터베이스의 관심사를 짐작하게 한다.
← 좌우로 밀어 보기 →

확장을 설치하려면 INSTALL 명령에 확장 이름을 붙여 입력한다. 그러면 확장은 데이터베이스에 설치되지만 적재되지는 않는다. 적재하려면 같은 이름에 LOAD를 붙인다. 이 기제는 멱등적(idempotent)이어서, 두 명령을 여러 번 내려도 오류가 나지 않는다.

NOTE

DuckDB 0.8 버전 이후로는, 설치된 확장이 필요하다고 판단되면 데이터베이스가 그것을 자동으로 적재한다. 그러므로 LOAD 명령이 필요하지 않을 수도 있다.

httpfs — 인터넷 저편의 파일을 읽는 문

기본 상태의 DuckDB는 인터넷 다른 곳에 있는 파일을 질의하지 못한다. 그 능력은 공식 확장 httpfs를 통해 얻는다. 배포판에 들어 있지 않다면 설치하고 적재한다.

httpfs 설치와 확인 2.4
D INSTALL httpfs;
D LOAD httpfs;

D FROM duckdb_extensions()
  SELECT loaded, installed, install_path
  WHERE extension_name = 'httpfs';
loadedinstalledinstall_path
booleanbooleanvarchar
truetrue/path/to/httpfs.duckdb_extension
이 확장은 파일을 로컬로 내려받지 않고도 HTTP(S) 서버에 놓인 파일을 직접 질의하게 해주며, S3와 그 밖의 몇몇 클라우드 스토리지 사업자도 지원한다.
← 좌우로 밀어 보기 →

여기서 문장 하나가 눈에 걸린다. 방금 그 질의는 FROM으로 시작해서 SELECT가 뒤에 온다. SQL을 배운 사람이라면 순서가 뒤집힌 것처럼 보일 텐데, DuckDB는 이 FROM 우선 구문을 허용한다. 사람이 실제로 생각하는 순서—어디서 가져와서, 무엇을 볼 것인가—를 그대로 적게 해주는 것이다. 이 장 마지막에 한 번 더 등장한다.

2.5

CLI로 CSV 파일 분석하기Analyzing a CSV file with the DuckDB CLI

이제 시연이다. 저자들이 고른 과제는 데이터 엔지니어라면 누구나 겪는 일—CSV 파일 안의 데이터가 무엇인지 알아내는 일이다. 데이터가 어디에 저장되어 있든 상관없다. 원격 HTTP 서버든 클라우드 스토리지(S3, GCP, HDFS)든, DuckDB는 수동으로 내려받아 가져오는 절차 없이 그것을 직접 처리한다. 게다가 CSV와 Parquet처럼 지원되는 여러 파일 형식의 수집은 기본적으로 병렬화되어 있으므로, 데이터를 DuckDB로 들이는 일은 번개처럼 빠르다.

저자들은 깃허브에서 CSV 파일을 찾다가 여러 나라의 총인구 수치를 담은 데이터셋을 발견했다. 우선 레코드가 몇 개인지 센다.

원격 CSV의 행 수 세기 2.5
D SELECT count(*)
  FROM 'https://github.com/bnokoro/Data-Science/raw/master/'
       'countries%20of%20the%20world.csv';
count_star()
int64
227
227개 나라의 인구 데이터를 확보했다. 파일을 내려받은 적도, 테이블을 만든 적도 없다.

확장자가 사라진 자리 — 짧은 링크의 함정

URL이나 파일 이름이 특정 확장자로 끝나면—여기서는 .csv—DuckDB가 알아서 처리한다. 그러면 같은 CSV 파일의 짧은 링크를 넣으면 어떻게 되는가.

확장자가 없는 URI 오류
D SELECT count(*)
  FROM 'https://bit.ly/3KoiZR0';

Error: Catalog Error: Table with name https://bit.ly/3KoiZR0 does not exist!
Did you mean "Player"?
LINE 1: select count(*) from 'https://bit.ly/3KoiZR0';
CSV 파일임에도 .csv 접미어가 없어서 DuckDB가 그것을 알지 못한다. 게다가 오류 메시지는 엉뚱하게 "Player"라는 테이블을 제안한다. URI를 테이블 이름으로 오해한 카탈로그가 가장 비슷한 이름을 찾아준 결과인데, 기계가 성실하게 헛다리를 짚는 장면이라 실소가 나온다.

해법은 read_csv_auto 함수다. 주어진 URI를 .csv 접미어가 없어도 CSV 파일인 것처럼 처리한다.

원격 파일의 형식을 명시하기 목록 2.5
D SELECT count(*)
  FROM read_csv_auto("https://bit.ly/3KoiZR0");
형식을 추론할 수 있는 정식 링크를 썼을 때와 같은 결과—227—가 돌아온다.

결과 모드 2.5.1

결과를 표시하는 방식은 .mode <name>으로 고를 수 있다. 쓸 수 있는 모드의 목록은 .help mode로 본다. 이 장에서 지금까지 써온 것은 duckbox 모드로, 유연한 표 구조를 돌려준다. DuckDB에는 여러 모드가 딸려 있고, 크게 두 갈래로 나뉜다.

  • 표 기반(table based) — 컬럼이 적을 때 잘 맞는다. duckbox, box, csv, ascii, table, list, column이 여기 속한다.
  • 줄 기반(line based) — 컬럼이 많을 때 잘 맞는다. json, jsonline, line이 여기 속한다.
  • 그 밖의 것 — 두 갈래에 들지 않는 것으로 html, insert, 그리고 아무것도 출력하지 않는 trash가 있다.

같은 결과가 모드에 따라 어떻게 달라지는지는 말로 설명하기보다 직접 갈아 끼워 보는 편이 빠르다. 아래는 이 장 끝에서 만들게 되는 서유럽 데이터의 첫 다섯 행을 여러 모드로 옮겨본 것이다.

CountryPopulationBirthrateDeathrate
varcharvarcharvarcharvarchar
Andorra71,2018,716,25
Austria8,192,8808,749,76
Belgium10,379,06710,3810,27
Denmark5,450,66111,1310,36
Faroe Islands47,24614,058,7
5 rows    4 columns
   Country = Andorra
Population = 71,201
 Birthrate = 8,71
 Deathrate = 6,25

   Country = Austria
Population = 8,192,880
 Birthrate = 8,74
 Deathrate = 9,76

   Country = Belgium
Population = 10,379,067
 Birthrate = 10,38
 Deathrate = 10,27
[{"Country":"Andorra","Population":"71,201","Birthrate":"8,71","Deathrate":"6,25"},
{"Country":"Austria","Population":"8,192,880","Birthrate":"8,74","Deathrate":"9,76"},
{"Country":"Belgium","Population":"10,379,067","Birthrate":"10,38","Deathrate":"10,27"}]
Country,Population,Birthrate,Deathrate
Andorra,"71,201","8,71","6,25"
Austria,"8,192,880","8,74","9,76"
Belgium,"10,379,067","10,38","10,27"
Denmark,"5,450,661","11,13","10,36"
Faroe Islands,"47,246","14,05","8,7"
Country        Population   Birthrate  Deathrate
-------------  -----------  ---------  ---------
Andorra        71,201       8,71       6,25
Austria        8,192,880    8,74       9,76
Belgium        10,379,067   10,38      10,27
Denmark        5,450,661    11,13      10,36
Faroe Islands  47,246       14,05      8,7
같은 데이터, 다른 옷. 컬럼이 적으면 표 기반이 읽기 좋고, 컬럼이 많으면 줄 기반이 낫다. 모드를 바꾸는 데 드는 비용은 점 명령 한 줄뿐이므로, 데이터의 모양에 옷을 맞추는 편이 늘 이득이다.
← 좌우로 밀어 보기 →

첫 질의는 CSV 파일의 레코드 수를 셌을 뿐이니, 이제 어떤 컬럼이 있는지가 궁금해진다. 그런데 컬럼이 많아서 기본 모드로는 상당수가 잘려 나간다. 그래서 질의를 돌리기 전에 line 모드로 바꾼다.

line 모드로 본 한 레코드 목록 2.6
D .mode line
D SELECT *
  FROM read_csv_auto("https://bit.ly/3KoiZR0")
  LIMIT 1;

                           Country = Afghanistan
                            Region = ASIA (EX. NEAR EAST)
                        Population = 31056997
                    Area (sq. mi.) = 647500
        Pop. Density (per sq. mi.) = 48,0
      Coastline (coast/area ratio) = 0,00
                     Net migration = 23,06
Infant mortality (per 1000 births) = 163,07
                GDP ($ per capita) = 700
                      Literacy (%) = 36,0
                 Phones (per 1000) = 3,2
                        Arable (%) = 12,13
                         Crops (%) = 0,22
                         Other (%) = 87,65
                           Climate = 1
                         Birthrate = 46,6
                         Deathrate = 20,34
                       Agriculture = 0,38
                          Industry = 0,24
                           Service = 0,38
컬럼 이름이 오른쪽으로 정렬되어 등호 앞에 나란히 서는 것이 line 모드의 모양새다. 48,0이나 163,07처럼 소수점 자리에 쉼표가 앉아 있는 것도 눈에 걸린다. 유럽식 표기로 기록된 원자료를 그대로 문자열로 읽어 들인 것이며, 수치로 다루려면 뒤에서 형 변환을 거쳐야 한다는 예고이기도 하다.
← 좌우로 밀어 보기 →

보다시피 line 모드는 duckbox보다 자리를 훨씬 많이 차지한다. 그러나 저자들의 경험으로는, 컬럼이 많은 데이터셋을 처음 탐색할 때 가장 좋은 모드다. 쓸 컬럼의 부분집합을 정한 다음에 다른 모드로 되돌아가면 된다.

이 데이터셋에는 여러 나라에 관한 흥미로운 정보가 많다. 나라의 수를 세고, 최대 인구와 전체 나라의 평균 면적을 구하는 질의를 써본다. 돌려받을 컬럼이 몇 개뿐이니 duckbox 모드로 되돌린다.

집계 질의 2.5.1
D .mode duckbox
D SELECT count(*) AS countries,
         max(Population) AS max_population,
         round(avg(cast("Area (sq. mi.)" AS decimal))) AS avgArea
  FROM read_csv_auto("https://bit.ly/3KoiZR0");
countriesmax_populationavgArea
int64int64double
2271313973713598227.0
면적 컬럼의 이름에 괄호와 점이 들어 있어 겹따옴표로 감싸야 하고, 문자열로 읽힌 값을 cast(... AS decimal)로 바꿔야 평균을 낼 수 있다. 원자료의 지저분함을 질의 안에서 곧바로 수습하는 이 방식이 DuckDB를 쓰는 맛이다.
← 좌우로 밀어 보기 →
여기까지 오는 동안 테이블은 하나도 만들지 않았다. 그리고 DuckDB가 실제로 할 수 있는 일의 빙산의 일각을 건드렸을 뿐이다. 2.5절을 맺으며

대화형을 벗어나 파이프라인으로

앞의 예들은 모두 대화형 모드에서 돌렸다. 그러나 DuckDB CLI는 비대화형으로도 동작한다. 표준 입력에서 읽고 표준 출력으로 쓴다. 그래서 온갖 종류의 파이프라인을 지어 올릴 수 있다.

이 장을 맺는 예제는 서유럽 나라들의 인구, 출생률, 사망률을 뽑아 새 로컬 CSV 파일을 만드는 스크립트다. DuckDB CLI에서 .exit로 나가거나, 다른 탭을 열어 실행한다.

셸 파이프라인 — CSV로 내보내기 2.5.1
$ duckdb -csv \
   -s "SELECT Country, Population, Birthrate, Deathrate
       FROM read_csv_auto('https://bit.ly/3KoiZR0')
       WHERE trim(region) = 'WESTERN EUROPE'" \
   > western_europe.csv

$ head -n6 western_europe.csv
trim(region)이 눈에 걸린다. 원자료의 지역 값에 앞뒤 공백이 붙어 있기 때문이며, 이런 자잘한 흠을 WHERE 절에서 바로 다듬는다.
표 2.1  western_europe.csv의 첫 여섯 줄 — 머리글과 데이터 다섯 행. 서유럽 몇 나라의 인구, 출생률, 사망률.
CountryPopulationBirthrateDeathrate
Andorra71,2018,716,25
Austria8,192,8808,749,76
Belgium10,379,06710,3810,27
Denmark5,450,66111,1310,36
Faroe Islands47,24614,058,7

Parquet은 리다이렉션으로 만들 수 없다

Parquet 파일도 만들 수 있다. 다만 출력을 .parquet 확장자를 가진 파일로 그대로 흘려보낼 수는 없다. 대신 COPY … TO 절에 파일 이름을 목적지로 지정한다. 이진 컬럼 형식이니 표준 출력으로 밀어낼 수 있는 물건이 아니라는, 당연하지만 놓치기 쉬운 구분이다.

Parquet 파일로 명시적으로 쓰기 목록 2.7
$ duckdb \
   -s "COPY (
         SELECT Country, Population, Birthrate, Deathrate
         FROM read_csv_auto('https://bit.ly/3KoiZR0')
         WHERE trim(region) = 'WESTERN EUROPE'
       ) TO 'western_europe.parquet' (FORMAT PARQUET)"

# 만든 Parquet 파일은 어떤 Parquet 판독기로도 볼 수 있다. DuckDB 자신으로도.
$ duckdb -s "FROM 'western_europe.parquet' LIMIT 5"
결과는 표 2.1과 같다. 마지막 줄에서 FROM 우선 구문이 다시 나온다. FROM 'western_europe.parquet' LIMIT 5—SELECT 절이 아예 없다. 읽어들일 곳만 지정하면 나머지는 알아서 하라는 이 간결함이, 이 장 전체의 태도와 닮았다.
SIDEBAR

되풀이되는 설정을 위한 설정 파일

반복되는 설정과 사용법은 $HOME/.duckdbrc에 놓인 설정 파일에 담아둘 수 있다. 이 파일은 시작할 때 읽히며, 그 안의 모든 명령—점 명령이든 SQL 명령이든—이 하나의 .read 명령을 통해 실행된다. 그래서 CLI의 설정 상태와, SQL 명령으로 초기화하고 싶은 것을 함께 저장해둘 수 있다.

이 파일에 넣을 만한 것의 예로 저자들은 맞춤 프롬프트와 환영 메시지를 든다. 오리 머리 모양의 프롬프트라니, 이 프로젝트의 유머 감각이 문서 곳곳에 배어 있다.

$HOME/.duckdbrc 사이드바
-- Duck head prompt
.prompt 'O> '

-- Example SQL statement
select 'Begin quacking now '||cast(now() as string) as "Ready, Set, ...";
SUMMARY

제2장이 남긴 다섯 문장Summary

  1. DuckDB는 Python, R, Java, JavaScript, Julia, C/C++, ODBC, WASM, Swift용 라이브러리로 제공된다.
  2. CLI는 출력 제어, 파일 읽기, 내장 도움말 등을 위한 점 명령을 추가로 지원한다.
  3. .modeduckbox, line, ascii 등 여러 표시 모드를 쓸 수 있다.
  4. httpfs 확장을 설치하면 HTTP 서버의 CSV 파일을 곧바로 질의할 수 있다.
  5. 외부 데이터셋을 질의하고 그 결과를 표준 출력이나 다른 파일로 써내면, 테이블을 만들지 않고도 CLI를 데이터 파이프라인의 한 단계로 쓸 수 있다.