TGViewer
Библиотека Go-разработчика | Golang Библиотека Go-разработчика | Golang @goproglib · 24.1K subscribers
Post #7094 2.94K
⭐️ go-duckfs: монтируем io/fs в DuckDB

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
More from @goproglib
  1. Sep 30, 2026🧑‍💻 Эмулятор AWS-сервисов Kumo — это небольшой инструмент на Go для локальной имитации A…
  2. Sep 29, 2026👨‍💻 Библиотека для написания LSP-серверов Написать свой Language Server с нуля на Go сло…
  3. Sep 28, 2026🤔 Вопрос с собеседования по Go Что выведет программа? ❤️ — 1 true / 0 false 🔥 — 1 true /…
  4. Sep 28, 2026👩‍💻 Что на самом деле происходит внутри Go map? После Go 1.24 обычный map внутри работае…
  5. Sep 26, 2026🔥 В Go 1.27 появился portable SIMD До этого SIMD-оптимизации в Go требовали архитектурног…
  6. Sep 25, 2026🤡🤡 📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека Go-разработчика #GoGiggle
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →