sqlx

Тема дорожной карты · Golang

sqlx — Golang-библиотека, строящаяся поверх стандартного пакета database/sql и добавляющая сканирование структур, именованные запросы и расширение IN-условий, которые иначе потребовали бы значительного шаблонного кода в чистом database/sql. Наиболее используемая возможность sqlx — db.StructScan и sqlx.Select(&users, query, args...), отображающие колонки SQL-результата напрямую на поля Go-структур через теги db:"", устраняя ручные вызовы rows.Scan и снижая риск ошибок позиционирования колонок. sqlx поддерживает все database/sql-совместимые драйверы — PostgreSQL через lib/pq (или pgx в stdlib-режиме), MySQL и SQLite, — поэтому существующий код на *sql.DB можно обновить до *sqlx.DB через sqlx.NewDb(db, driverName) без изменения логики соединения. Поддержка именованных запросов (db.NamedExec, db.PrepareNamed) позволяет писать INSERT INTO users (name) VALUES (:name) с аргументом-структурой, предотвращая ошибки позиционных параметров в сложных DML-запросах. Для Golang-проектов, предпочитающих оставаться близко к SQL вместо использования ORM вроде GORM, sqlx обеспечивает правильный уровень абстракции — контроль над сырыми запросами с эргономичным маппингом результатов и полной интеграцией с инструментами миграций вроде golang-migrate.

Как это работает

sqlx использует database/sql (интерфейс) + драйвер (pgx для Postgres — также экспонирует свой native-API, go-sql-driver/mysql для MySQL, mattn/go-sqlite3 для SQLite). Connection pool встроен в database/sql. ORM: GORM (популярный, full-featured, opinionated), Ent (Facebook, code-gen based), Bun (sqlx-like), sqlx (расширяет stdlib). Для миграций: golang-migrate, goose, atlas.

Когда применять

По умолчанию сырой database/sql + sqlx для явных запросов; ORM (GORM, Ent) — только если команда реально хочет. pgx напрямую (pgxpool) — для Postgres: лучшая производительность + Postgres-специфика (массивы, JSONB, COPY). Всегда параметризованные запросы ($1/? placeholders). Миграции — через тул, не через Go-код.

Типичные ошибки

Ловушки sqlx: SQL-инъекция через fmt.Sprintf в запрос (всегда параметризуйте); утечка *sql.Rows (всегда defer rows.Close()); магия GORM прячет N+1 запросы; не выставлен db.SetMaxOpenConns — исчерпание соединений Postgres; context.Background() вместо контекста запроса (запросы нельзя отменить).

Связанные понятия

Полезные ресурсы