DuckDB умеет читать Parquet, CSV и JSON прямо из S3, HTTP и других источников. Но его встроенные расширения —
httpfs, aws — написаны на C++. Они живут в отдельном I/O-стеке, не видят ваш Go-код, не участвуют в трейсинге и не уважают ваши политики доступа. go-duckfs решает эту проблему.Что делает библиотека
Пакет монтирует любой
io/fs.FS как виртуальную файловую систему внутрь DuckDB. Всё I/O, которое DuckDB делает при выполнении запросов, проходит через Go-рантайм. Это значит, что вы можете использовать нативные Go SDK облачных провайдеров, оборачивать доступ в middleware для метрик и логов, контролировать доступ на уровне приложения.Установка и сборка
Пакет требует динамической линковки DuckDB. Рекомендуемый способ через pixi:
# Установить DuckDB
pixi install --locked
# Собрать с динамической линковкой
CGO_ENABLED=1 \
CGO_LDFLAGS="-L.pixi/envs/default/lib" \
go build -tags=duckdb_use_lib
Тег
duckdb_use_lib обязателен. Он переключает Go-биндинги DuckDB в режим динамической линковки.Базовый пример:
c, err := duckfs.Open("", nil, os.DirFS("testdata"))
if err != nil {
log.Fatal(err)
}
db := sql.OpenDB(c)
defer db.Close()
rows, err := db.Query(`SELECT * FROM read_parquet('data.parquet')`)duckfs.Open создаёт коннектор с вашим fs.FS в качестве файловой системы. Дальше — стандартный sql.DB. DuckDB при выполнении запроса обращается к файлам через ваш Go-код, а не напрямую.Протокольные пути
DuckDB использует URI-подобные пути вида
myproto://file.parquet. Если хотите сохранить такой префикс в запросах, оберните свою реализацию fs.FS:type myFS struct {
fsys fs.FS
}
func (f *myFS) Open(name string) (fs.File, error) {
name = strings.TrimPrefix(name, "myproto://")
return f.fsys.Open(name)
}
c, err := duckfs.Open("", nil, &myFS{fsys: os.DirFS("data")})
if err != nil {
log.Fatal(err)
}
db := sql.OpenDB(c)
row := db.QueryRow(`SELECT * FROM read_csv('myproto://records.csv')`)Это удобно, если DuckDB-запросы генерируются автоматически и вы хотите разграничить разные источники данных по префиксу.
Запуск тестов:
CGO_ENABLED=1 \
CGO_LDFLAGS="-L.pixi/envs/default/lib" \
LD_LIBRARY_PATH=".pixi/envs/default/lib" \
go test -v ./... -tags=duckdb_use_lib
Когда это полезно
Если вы используете DuckDB в Go-сервисе и хотите читать данные из S3, GCS или любого другого хранилища через собственный Go-клиент
go-duckfs даёт для этого готовый мост. Трейсинг, ретраи, авторизация, кастомные заголовки — всё остаётся на вашей стороне, в Go, а не уходит в C++-расширение DuckDB.➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction
