Go 클라이언트
Go 클라이언트
DuckDB Go 클라이언트인 duckdb-go는 Go에 내장된 database/sql 인터페이스를 따르는 SQL 드라이버예요. 그래서 DuckDB를 다른 Go SQL 데이터베이스와 동일한 API로 사용할 수 있답니다. 함께 살펴볼까요?
출처: 문서
본문
DuckDB Go 클라이언트의 최신 안정 릴리스는 DuckDB {% if site.current_duckdb_go_version != "" %}{{ site.current_duckdb_go_version }}{% else %}{{ site.lts_duckdb_go_version }}{% endif %}를 번들해요. 자체 버전 태그가 그 DuckDB 버전을 인코딩해요. 아래 버전 관리를 참고하세요.
DuckDB Go 클라이언트인 duckdb-go는 Go에 내장된 database/sql 인터페이스를 따르는 SQL 드라이버예요. 그래서 DuckDB는 다른 Go SQL 데이터베이스와 같은 API로 사용돼요. database/sql 위에, 이 클라이언트는 [Appender]({% link docs/current/clients/go/data_import.md %}#appender), [Apache Arrow]({% link docs/current/clients/go/result_handling.md %}), [사용자 정의 함수]({% link docs/current/clients/go/functions.md %}), [프로파일링]({% link docs/current/clients/go/profiling.md %})을 위한 DuckDB 특화 인터페이스를 추가해요. 이 페이지는 설치에 집중해요. 이 섹션의 다른 페이지들은 연결과 각 기능을 자세히 다뤄요.
database/sql 인터페이스에 대한 일반 지침은 공식 문서와 Go database access 튜토리얼을 참고하세요.
설치 (Installation)
이 클라이언트는 Go 모듈이에요. /v2 메이저 버전 접미사를 사용해 go get으로 프로젝트에 추가하세요:
go get github.com/duckdb/duckdb-go/v2
모듈의 의존성을 프로젝트의 vendor 디렉토리에 복사하려면, duckdb-go-bindings의 사전 빌드된 DuckDB 라이브러리를 포함해서 go mod vendor를 실행하세요.
DuckDB는 C++로 작성되었기 때문에 이 클라이언트는 cgo를 사용하고 빌드에 C 컴파일러가 필요해요. 기본적으로 사전 빌드된 DuckDB 라이브러리를 바이너리에 정적으로 링크하므로 별도의 DuckDB 설치가 필요 없어요. 사전 빌드 라이브러리는 macOS (amd64, arm64), Linux (amd64, arm64), Windows (amd64) 용으로 제공돼요. 다른 플랫폼, 커스텀 빌드, 동적 링킹은 [Troubleshoot]({% link docs/current/clients/go/troubleshoot.md %}#linking-duckdb)에서 다뤄요.
가져오기 (Importing)
드라이버를 등록하려면 database/sql과 함께 빈 식별자(blank identifier)로 패키지를 사이드 이펙트용으로 가져오세요:
import (
"database/sql"
_ "github.com/duckdb/duckdb-go/v2"
)
이 import는 database/sql에 duckdb라는 드라이버를 등록해요. Appender나 사용자 정의 함수처럼 클라이언트 자체 타입과 함수를 직접 호출하는 코드는 빈 식별자 대신 duckdb 이름으로 패키지를 가져와요:
import "github.com/duckdb/duckdb-go/v2"
버전 관리 (Versioning)
DuckDB v1.5.0부터 duckdb-go 버전은 번들하는 DuckDB 버전을 세메버(semantic-versioning)의 두 번째 구성 요소에 인코딩해요. 그 구성 요소는 DuckDB major, minor, patch 숫자를 이어붙인 것으로, minor와 patch는 각각 두 자리로 제로 패딩돼요: DuckDB v1.5.0은 duckdb-go v2.10500.x에 매핑되고, DuckDB {{ site.current_duckdb_go_version }}은 v2.10505.0에 매핑돼요. README에는 이전 릴리스에 대한 전체 매핑 표가 있어요.
DuckDB 1.4 Andium에 머무는 LTS 릴리스 라인은 클라이언트의 이전 버전 관리 방식을 따르는 자체 태그로 게시돼요. 다른 버전과 마찬가지로 go.mod에서 하나를 선택하세요. 사용 가능한 태그는 releases 페이지를 참고하세요.
이 프로젝트는 v2.5.0부터
github.com/marcboeker/go-duckdb에서github.com/duckdb/duckdb-go로 이동했어요. v2.5.0 이전의 모든 버전은 이전 import 경로를 사용해요. 아래 Migrating frommarcboeker/go-duckdb를 참고하세요.
기본 API 사용법 (Basic API Usage)
sql.Open()으로 드라이버 이름 duckdb와 데이터 소스 이름 (DSN)을 전달해서 데이터베이스를 열어요. 빈 DSN이거나 :memory: DSN이면 인메모리 데이터베이스를 열고, 파일 경로면 영속 데이터베이스를 열거나 생성해요. 거기서부터 Exec, Query, QueryRow가 다른 어떤 database/sql 드라이버와 똑같이 문장을 실행해요:
package main
import (
"database/sql"
"errors"
"fmt"
"log"
_ "github.com/duckdb/duckdb-go/v2"
)
func main() {
db, err := sql.Open("duckdb", "")
if err != nil {
log.Fatal(err)
}
defer db.Close()
_, err = db.Exec(`CREATE TABLE people (id INTEGER, name VARCHAR)`)
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(`INSERT INTO people VALUES (42, 'John')`)
if err != nil {
log.Fatal(err)
}
var (
id int
name string
)
row := db.QueryRow(`SELECT id, name FROM people`)
err = row.Scan(&id, &name)
if errors.Is(err, sql.ErrNoRows) {
log.Println("no rows")
} else if err != nil {
log.Fatal(err)
}
fmt.Printf("id: %d, name: %s\n", id, name)
}
이 예시는 클라이언트의 simple 예시를 따라가요. [Run Queries]({% link docs/current/clients/go/querying.md %})에서 쿼리 보내기, 파라미터 바인딩, 결과 읽기를 자세히 다뤄요.
데이터 소스 이름 (Data Source Names)
sql.Open()에 전달되는 DSN은 데이터베이스 경로 뒤에 선택적인 [DuckDB 구성 옵션]({% link docs/current/configuration/overview.md %})을 URL 스타일 쿼리 파라미터로 붙인 형태예요:
// 인메모리 데이터베이스: 빈 DSN과 ":memory:"는 동일해요.
db, err := sql.Open("duckdb", "")
// 영속 데이터베이스, 존재하지 않으면 생성돼요.
db, err := sql.Open("duckdb", "/path/to/foo.db")
// 구성 옵션을 가진 영속 데이터베이스.
db, err := sql.Open("duckdb", "/path/to/foo.db?access_mode=read_only&threads=4")
첫 쿼리 전에 SET 문장 같은 초기화 단계를 실행하려면 sql.OpenDB()와 Connector로 데이터베이스를 열어요. 커넥터, 구성, 연결 수명은 [Connect]({% link docs/current/clients/go/connecting.md %})를 참고하세요.
빌드 태그 (Build Tags)
일부 클라이언트 기능은 Go build tags 뒤에 게이트되어 있고, go build에 -tags 플래그로 전달돼요, 예를 들어 go build -tags=duckdb_arrow. 사용 가능한 태그:
| Build tag | 활성화하는 것 |
|---|---|
duckdb_arrow |
[Apache Arrow 인터페이스]({% link docs/current/clients/go/result_handling.md %}). 무거운 의존성이라 opt-in이에요. |
duckdb_use_lib |
번들된 것을 정적으로 링크하는 대신 시스템의 DuckDB 라이브러리에 동적으로 링크해요. [Troubleshoot]({% link docs/current/clients/go/troubleshoot.md %}#linking-a-dynamic-library) 참고. |
duckdb_use_static_lib |
번들된 것 대신 커스텀 DuckDB 정적 라이브러리에 정적으로 링크해요. [Troubleshoot]({% link docs/current/clients/go/troubleshoot.md %}#linking-a-custom-static-library) 참고. |
번들 확장 (Bundled Extensions)
모든 사전 빌드 라이브러리는 DuckDB의 기본 확장을 정적으로 링크해요: [ICU]({% link docs/current/core_extensions/icu.md %}), [JSON]({% link docs/current/data/json/overview.md %}), [Parquet]({% link docs/current/data/parquet/overview.md %}), [Autocomplete]({% link docs/current/core_extensions/autocomplete.md %}). [자동 확장 로드]({% link docs/current/extensions/overview.md %}#autoloading-extensions)도 활성화되어 있어, 다른 핵심 확장이 첫 사용 시 설치되고 로드돼요.
marcboeker/go-duckdb에서 마이그레이션 (Migrating from marcboeker/go-duckdb)
이 프로젝트는 v2.5.0에서 github.com/marcboeker/go-duckdb에서 github.com/duckdb/duckdb-go로 이동했어요. 프로젝트를 마이그레이션하려면 의존성을 업데이트하고 gofmt로 import 경로를 다시 써요:
# 의존성 업데이트.
go get github.com/duckdb/duckdb-go/[email protected]
# import 경로 재작성.
gofmt -w -r '"github.com/marcboeker/go-duckdb/v2" -> "github.com/duckdb/duckdb-go/v2"' .
# mapping 또는 arrowmapping 서브모듈을 사용한다면 다음도 실행:
gofmt -w -r '"github.com/marcboeker/go-duckdb/mapping" -> "github.com/duckdb/duckdb-go/v2/mapping"' .
gofmt -w -r '"github.com/marcboeker/go-duckdb/arrowmapping" -> "github.com/duckdb/duckdb-go/v2/arrowmapping"' .
# 정리.
go mod tidy
v2로 이동하면서 opt-in Arrow 지원과 더 엄격한 JSON 스캐닝을 포함한 몇 가지 breaking change도 도입됐어요. 전체 목록은 [Troubleshoot]({% link docs/current/clients/go/troubleshoot.md %}#scanning-json-values)와 README를 참고하세요.
더 읽을거리 (Further Reading)
- [Connect]({% link docs/current/clients/go/connecting.md %}) — 인메모리 및 파일 기반 데이터베이스 열기, DSN 구성, 커넥터, 연결 수명.
- [Run Queries]({% link docs/current/clients/go/querying.md %}) —
Exec,Query, 준비된 문, 파라미터 바인딩, 트랜잭션, 결과를 Go 값으로 스캔. - [Import Data]({% link docs/current/clients/go/data_import.md %}) — Appender로 대량 로드하고 Parquet, CSV, JSON 파일에서 직접 읽기.
- [Handle Results]({% link docs/current/clients/go/result_handling.md %}) — 컬럼형 결과 교환을 위한 Apache Arrow 인터페이스.
- [Write User Defined Functions]({% link docs/current/clients/go/functions.md %}) — 스칼라 및 테이블 사용자 정의 함수, replacement scans.
- [Profile and Monitor]({% link docs/current/clients/go/profiling.md %}) — 쿼리 프로파일링과 로깅.
- [Troubleshoot]({% link docs/current/clients/go/troubleshoot.md %}) — 링킹, cgo, Windows 설정, 기타 빌드 및 런타임 이슈.
- [Clients Overview]({% link docs/current/clients/overview.md %}) — DuckDB가 Go와 함께 제공하는 다른 클라이언트 API.
감사의 말 (Acknowledgements)
DuckDB Go 클라이언트의 초기 구현을 만들어 주시고, DuckDB 팀과의 공동 노력의 일부로 계속 작업해 주신 Marc Boeker님께 감사드려요.