Generated banner for Golang Database
Generated logo for Golang Database

Golang Database

Samuel BertheCommunityCreated by samberDistributed by Samuel Berthe

  • Skill
  • Tool integration
  • Software development
  • MIT
  • No issues found

From the author

Comprehensive guide for Go database access — parameterized queries, struct scanning, NULLable columns, transactions, isolation levels, SELECT FOR UPDATE, connection pool, batch processing, context propagation, and migration tooling. Use when writing, reviewing, or debugging Golang code that interacts with PostgreSQL, MariaDB, MySQL, or SQLite; for database testing; or for questions about database/sql, sqlx, or pgx. Does NOT generate database schemas or migration SQL.
— the description by samber

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a set of best practices for interacting with databases in Go using standard libraries like database/sql, sqlx, or pgx. It emphasizes explicit SQL usage over ORMs, focusing on security, performance, and maintainability. The guide covers essential topics including parameterized queries to prevent SQL injection, proper context propagation, transaction management, connection pool configuration, and robust error handling. It is designed for backend engineers who prioritize observable and reliable database code.

What it does

  • Provides patterns for secure, parameterized SQL queries to prevent injection.
  • Outlines best practices for struct scanning and handling NULLable database columns.
  • Defines standards for transaction management and isolation levels.
  • Explains how to configure and monitor database connection pools for performance.
  • Details proper error handling and context propagation for database operations.
  • Offers guidance on choosing between database/sql, sqlx, and pgx.

When to use it

  • When writing new repository functions or query helpers in Go.
  • When auditing existing Go code for database-related bugs or security vulnerabilities.
  • When debugging performance issues related to connection pooling or query execution.
  • When determining the best approach for mapping database rows to Go structs.

Advantages

  • Promotes explicit, readable SQL that is easier to debug and test.
  • Reduces the risk of SQL injection through mandatory parameterization.
  • Improves application reliability by enforcing proper resource management like closing rows.
  • Helps optimize database performance through correct connection pool settings.

Usage examples

“How do I safely query a user by email in Go without using an ORM?”
The agent will provide a code snippet using db.GetContext with a parameterized placeholder ($1 or ?) to ensure the query is safe from SQL injection.
“Review this code for database connection leaks.”
The agent will scan the provided code for missing defer rows.Close() calls or improper use of db.Query instead of db.Exec.
“How should I handle a NULLable column in my database struct?”
The agent will recommend using pointer fields (e.g., *string) for struct members and explain how they interact with database scanning and JSON marshaling.
“What are the recommended settings for my database connection pool?”
The agent will provide a configuration block for SetMaxOpenConns, SetMaxIdleConns, and related methods, explaining the trade-offs for each.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/samber/golang-database/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip golang-database.zip -d .agents/skills

Documentation by samber

Persona: You are a Go backend engineer who writes safe, explicit, and observable database code. You treat SQL as a first-class language — no ORMs, no magic — and you catch data integrity issues at the boundary, not deep in the application.

Modes:

  • Write mode — generating new repository functions, query helpers, or transaction wrappers: follow the skill's sequential instructions; launch a background agent to grep for existing query patterns and naming conventions in the codebase before generating new code.

  • Review/debug mode — auditing or debugging existing database code: use a sub-agent to scan for missing rows.Close(), un-parameterized queries, missing context propagation, and absent error checks in parallel with reading the business logic.

Community default. A company skill that explicitly supersedes samber/cc-skills-golang@golang-database skill takes precedence.

Go Database Best Practices

Go's database/sql provides a solid foundation for database access. Use sqlx or pgx on top of it for ergonomics — never an ORM.

When using sqlx or pgx, refer to the library's official documentation and code examples for current API signatures.

Best Practices Summary

  1. Use sqlx or pgx, not ORMs — ORMs hide SQL, generate unpredictable queries, and make debugging harder

  2. Queries MUST use parameterized placeholders — NEVER concatenate user input into SQL strings

  3. Context MUST be passed to all database operations — use *Context method variants (QueryContext, ExecContext, GetContext)

  4. sql.ErrNoRows MUST be handled explicitly — distinguish "not found" from real errors using errors.Is

  5. Rows MUST be closed after iteration — defer rows.Close() immediately after QueryContext calls

  6. NEVER use db.Query for statements that don't return rows — Query returns *Rows which must be closed; if you forget, the connection leaks back to the pool. Use db.Exec instead

  7. Use transactions for multi-statement operations — wrap related writes in BeginTxx/Commit

  8. Use SELECT ... FOR UPDATE when reading data you intend to modify — prevents race conditions

  9. Set custom isolation levels when default READ COMMITTED is insufficient (e.g., serializable for financial operations)

  10. Handle NULLable columns with pointer fields (*string, *int) or sql.NullXxx types

  11. Connection pool MUST be configured — SetMaxOpenConns, SetMaxIdleConns, SetConnMaxLifetime, SetConnMaxIdleTime

  12. Use external tools for migrations — golang-migrate or Flyway, never hand-rolled or AI-generated migration SQL

  13. Batch operations in reasonable sizes — not row-by-row (too many round trips), not millions at once (locks and memory)

  14. Never create or modify database schemas — a schema that looks correct on toy data can create hotspots, lock contention, or missing indexes under real production load. Schema design requires understanding of data volumes, access patterns, and production constraints that AI does not have

  15. Avoid hidden SQL features — do not rely on triggers, views, materialized views, stored procedures, or row-level security in application code

Library Choice

LibraryBest forStruct scanningPostgreSQL-specific
database/sqlPortability, minimal depsManual ScanNo
sqlxMulti-database projectsStructScanNo
pgxPostgreSQL (30-50% faster)pgx.RowToStructByNameYes (COPY, LISTEN, arrays)
GORM/entAvoidMagicAbstracted away

Why NOT ORMs:

  • Unpredictable query generation — N+1 problems you cannot see in code

  • Magic hooks and callbacks (BeforeCreate, AfterUpdate) make debugging harder

  • Schema migrations coupled to application code

  • Learning the ORM API is harder than learning SQL, and the abstraction leaks

Parameterized Queries

// ✗ VERY BAD — SQL injection vulnerability
query := fmt.Sprintf("SELECT * FROM users WHERE email = '%s'", email)

// ✓ Good — parameterized (PostgreSQL)
var user User
err := db.GetContext(ctx, &user, "SELECT id, name, email FROM users WHERE email = $1", email)

// ✓ Good — parameterized (MySQL)
err := db.GetContext(ctx, &user, "SELECT id, name, email FROM users WHERE email = ?", email)
Dynamic IN clauses
query, args, err := sqlx.In("SELECT * FROM users WHERE id IN (?)", ids)
if err != nil {
    return fmt.Errorf("building IN clause: %w", err)
}
query = db.Rebind(query) // adjust placeholders for your driver
err = db.SelectContext(ctx, &users, query, args...)
Dynamic column names

Never interpolate column names from user input. Use an allowlist:

allowed := map[string]bool{"name": true, "email": true, "created_at": true}
if !allowed[sortCol] {
    return fmt.Errorf("invalid sort column: %s", sortCol)
}
query := fmt.Sprintf("SELECT id, name, email FROM users ORDER BY %s", sortCol)

For more injection prevention patterns, see the samber/cc-skills-golang@golang-security skill.

Struct Scanning and NULLable Columns

Use db:"column_name" tags for sqlx, pgx.CollectRows with pgx.RowToStructByName for pgx. Handle NULLable columns with pointer fields (*string, *time.Time) — they work cleanly with both scanning and JSON marshaling. See Scanning Reference for examples of all approaches.

Error Handling

func GetUser(id string) (*User, error) {
    var user User

    err := db.GetContext(ctx, &user, "SELECT id, name FROM users WHERE id = $1", id)
    if err != nil {
        if errors.Is(err, sql.ErrNoRows) {
            return nil, ErrUserNotFound // translate to domain error
        }
        return nil, fmt.Errorf("querying user %s: %w", id, err)
    }

    return &user, nil
}

or:

func GetUser(id string) (u *User, exists bool, err error) {
    var user User

    err := db.GetContext(ctx, &user, "SELECT id, name FROM users WHERE id = $1", id)
    if err != nil {
        if errors.Is(err, sql.ErrNoRows) {
            return nil, false, nil // "no user" is not a technical error, but a domain error
        }
        return nil, false, fmt.Errorf("querying user %s: %w", id, err)
    }

    return &user, true, nil
}
Always close rows
rows, err := db.QueryContext(ctx, "SELECT id, name FROM users")
if err != nil {
    return fmt.Errorf("querying users: %w", err)
}
defer rows.Close() // prevents connection leaks

for rows.Next() {
    // ...
}
if err := rows.Err(); err != nil { // always check after iteration
    return fmt.Errorf("iterating users: %w", err)
}
Common database error patterns
ErrorHow to detectAction
Row not founderrors.Is(err, sql.ErrNoRows)Return domain error
Unique constraintCheck driver-specific error codeReturn conflict error
Connection refusederr != nil on db.PingContextFail fast, log, retry with backoff
Serialization failurePostgreSQL error code 40001Retry the entire transaction
Context cancelederrors.Is(err, context.Canceled)Stop processing, propagate

Context Propagation

Always use the *Context method variants to propagate deadlines and cancellation:

// ✗ Bad — no context, query runs until completion even if client disconnects
db.Query("SELECT ...")

// ✓ Good — respects context cancellation and timeouts
db.QueryContext(ctx, "SELECT ...")

For context patterns in depth, see the samber/cc-skills-golang@golang-context skill.

Transactions, Isolation Levels, and Locking

For transaction patterns, isolation levels, SELECT FOR UPDATE, and locking variants, see Transactions.

Connection Pool

db.SetMaxOpenConns(25)              // limit total connections
db.SetMaxIdleConns(10)              // keep warm connections ready
db.SetConnMaxLifetime(5 * time.Minute)  // recycle stale connections
db.SetConnMaxIdleTime(1 * time.Minute)  // close idle connections faster

For sizing guidance and formulas, see Database Performance.

Migrations

Use an external migration tool. Schema changes require human review with understanding of data volumes, existing indexes, foreign keys, and production constraints.

Recommended tools:

  • golang-migrate — CLI + Go library, supports all major databases

  • Flyway — JVM-based, widely used in enterprise environments

  • Atlas — modern, declarative schema management

Migration SQL should be written and reviewed by humans, versioned in source control, and applied through CI/CD pipelines.

Avoid Hidden SQL Features

Do not rely on triggers, views, materialized views, stored procedures, or row-level security in application code — they create invisible side effects and make debugging impossible. Keep SQL explicit and visible in Go where it can be tested and version-controlled.

Schema Creation

This skill does NOT cover schema creation. AI-generated schemas are often subtly wrong — missing indexes, incorrect column types, bad normalization, or missing constraints. Schema design requires understanding data volumes, access patterns, query profiles, and business constraints. Use dedicated database tooling and human review.

Deep Dives

  • Transactions — Transaction boundaries, isolation levels, deadlock prevention, SELECT FOR UPDATE

  • Testing Database Code — Mock connections, integration tests with containers, fixtures, schema setup/teardown

  • Database Performance — Connection pool sizing, batch processing, indexing strategy, query optimization

  • Struct Scanning — Struct tags, NULLable column handling, JSON marshaling patterns

Cross-References

  • → See samber/cc-skills-golang@golang-security skill for SQL injection prevention patterns

  • → See samber/cc-skills-golang@golang-context skill for context propagation to database operations

  • → See samber/cc-skills-golang@golang-error-handling skill for database error wrapping patterns

  • → See samber/cc-skills-golang@golang-testing skill for database integration test patterns

References

Files

evals/evals.json

[
  {
    "id": 1,
    "name": "orm-vs-sqlx-pgx-recommendation",
    "description": "Tests whether the model recommends sqlx/pgx over ORMs and explains why ORMs are harmful",
    "prompt": "I'm starting a new Go web application with PostgreSQL. I need to set up database access. What library should I use? I've heard GORM is popular and has good docs. Can you set up the database layer for me?",
    "trap": "Without the skill, the model may recommend GORM since it's popular and widely known. The skill explicitly says to avoid ORMs and use sqlx or pgx.",
    "assertions": [
      {"id": "1.1", "text": "Recommends sqlx or pgx instead of GORM"},
      {"id": "1.2", "text": "Explains why ORMs are problematic (N+1 queries, unpredictable SQL generation, magic hooks, or debugging difficulty)"},
      {"id": "1.3", "text": "Recommends pgx specifically for PostgreSQL-only projects due to performance advantage (30-50% faster)"},
      {"id": "1.4", "text": "Does NOT set up GORM or ent as the primary database library"},
      {"id": "1.5", "text": "Mentions that learning the ORM API is harder than learning SQL or that ORMs hide SQL"}
    ]
  },
  {
    "id": 2,
    "name": "exec-vs-query-for-non-select",
    "description": "Tests the subtle rule that db.Query must NOT be used for statements that don't return rows",
    "prompt": "Write a Go function that deletes expired sessions from a PostgreSQL database. Use sqlx. The function should delete all sessions where expires_at < now() and return the number of deleted rows.",
    "trap": "The model may use db.QueryContext or db.Query for the DELETE statement, which returns *Rows that must be closed. The skill says to use db.Exec for statements that don't return rows.",
    "assertions": [
      {"id": "2.1", "text": "Uses ExecContext (not QueryContext or Query) for the DELETE statement"},
      {"id": "2.2", "text": "Uses the *Context variant (ExecContext, not Exec)"},
      {"id": "2.3", "text": "Passes ctx to the database call"},
      {"id": "2.4", "text": "Retrieves RowsAffected() from the result to return the count"},
      {"id": "2.5", "text": "Uses parameterized query (not string concatenation)"}
    ]
  },
  {
    "id": 3,
    "name": "nullable-column-handling",
    "description": "Tests whether pointer fields are preferred for NULLable columns over sql.NullXxx types",
    "prompt": "I have a PostgreSQL users table with columns: id (int), name (text NOT NULL), bio (text, nullable), deleted_at (timestamptz, nullable). Write a Go struct that I can use with sqlx for scanning and also marshal to JSON properly. The bio should be omitted from JSON when NULL, and deleted_at should appear as null in JSON.",
    "trap": "Without the skill, the model may use sql.NullString and sql.NullTime which require custom JSON marshaling. The skill recommends pointer fields as the cleanest approach.",
    "assertions": [
      {"id": "3.1", "text": "Uses pointer types (*string for bio, *time.Time for deleted_at) rather than sql.NullString/sql.NullTime"},
      {"id": "3.2", "text": "Includes db struct tags for sqlx (db:\"column_name\")"},
      {"id": "3.3", "text": "Includes json struct tags"},
      {"id": "3.4", "text": "Uses json:\"bio,omitempty\" for bio (omitted when NULL)"},
      {"id": "3.5", "text": "Uses json:\"deleted_at\" without omitempty for deleted_at (appears as null)"}
    ]
  },
  {
    "id": 4,
    "name": "connection-pool-configuration",
    "description": "Tests that connection pool settings are configured with all four parameters and reasonable values",
    "prompt": "Write a Go function that creates a new sqlx database connection to PostgreSQL and returns *sqlx.DB. Just the basic setup, nothing fancy.",
    "trap": "Without the skill, the model often returns the *sqlx.DB without configuring the connection pool. The skill requires all four pool settings.",
    "assertions": [
      {"id": "4.1", "text": "Calls SetMaxOpenConns on the database connection"},
      {"id": "4.2", "text": "Calls SetMaxIdleConns on the database connection"},
      {"id": "4.3", "text": "Calls SetConnMaxLifetime on the database connection"},
      {"id": "4.4", "text": "Calls SetConnMaxIdleTime on the database connection"},
      {"id": "4.5", "text": "MaxIdleConns is less than or equal to MaxOpenConns"}
    ]
  },
  {
    "id": 5,
    "name": "rows-close-and-err-check",
    "description": "Tests proper handling of rows iteration: defer Close and rows.Err() check after loop",
    "prompt": "Write a Go function using sqlx that lists all active users (active = true) from a users table. Return a slice of User structs. Use db.QueryContext, not db.SelectContext — I want to handle scanning manually for learning purposes.",
    "trap": "Without the skill, the model may forget to defer rows.Close() or skip the rows.Err() check after iteration, both of which are required.",
    "assertions": [
      {"id": "5.1", "text": "Calls defer rows.Close() immediately after the QueryContext call (before the loop)"},
      {"id": "5.2", "text": "Checks rows.Err() after the for rows.Next() loop completes"},
      {"id": "5.3", "text": "Returns the error from rows.Err() if non-nil"},
      {"id": "5.4", "text": "Uses QueryContext (not Query) with a context parameter"},
      {"id": "5.5", "text": "Checks the error returned by QueryContext before proceeding"}
    ]
  },
  {
    "id": 6,
    "name": "errnorows-handling-pattern",
    "description": "Tests proper sql.ErrNoRows handling with domain error translation",
    "prompt": "Write a Go function GetUserByEmail(ctx context.Context, db *sqlx.DB, email string) that returns the user or an appropriate error when not found. Use sqlx.GetContext.",
    "trap": "Without the skill, the model may return the raw sql.ErrNoRows error directly or not distinguish it from other errors. The skill requires translating to a domain error.",
    "assertions": [
      {"id": "6.1", "text": "Uses errors.Is(err, sql.ErrNoRows) to check for not-found"},
      {"id": "6.2", "text": "Returns a domain-specific error (e.g. ErrUserNotFound) when no rows, NOT the raw sql.ErrNoRows"},
      {"id": "6.3", "text": "Wraps non-ErrNoRows errors with context using fmt.Errorf and %w"},
      {"id": "6.4", "text": "Uses GetContext (not Get) with the ctx parameter"},
      {"id": "6.5", "text": "Uses parameterized query placeholder ($1 or ?) not string concatenation"}
    ]
  },
  {
    "id": 7,
    "name": "transaction-with-defer-rollback",
    "description": "Tests the correct transaction pattern: BeginTxx, defer Rollback, Commit",
    "prompt": "Write a Go function TransferFunds(ctx, db, fromAccountID, toAccountID string, amount int) that transfers money between two accounts atomically. Use sqlx.",
    "trap": "Without the skill, the model may forget defer tx.Rollback(), use wrong isolation level for financial operations, or miss SELECT FOR UPDATE.",
    "assertions": [
      {"id": "7.1", "text": "Uses BeginTxx (or BeginTx) to start a transaction"},
      {"id": "7.2", "text": "Calls defer tx.Rollback() immediately after BeginTxx"},
      {"id": "7.3", "text": "Uses SELECT ... FOR UPDATE when reading balances to prevent race conditions"},
      {"id": "7.4", "text": "Sets serializable or repeatable-read isolation level (financial operation)"},
      {"id": "7.5", "text": "Calls tx.Commit() at the end of the successful path"}
    ]
  },
  {
    "id": 8,
    "name": "dynamic-in-clause-with-rebind",
    "description": "Tests proper handling of dynamic IN clauses with sqlx.In and Rebind",
    "prompt": "Write a Go function that fetches users by a list of IDs from PostgreSQL using sqlx. The function receives a []int64 of user IDs.",
    "trap": "Without the skill, the model may try to use a raw IN ($1) placeholder or manually build the query string. The skill shows sqlx.In + Rebind pattern.",
    "assertions": [
      {"id": "8.1", "text": "Uses sqlx.In() to expand the IN clause placeholders"},
      {"id": "8.2", "text": "Calls db.Rebind() on the query after sqlx.In to adjust placeholders for the driver"},
      {"id": "8.3", "text": "Passes the expanded args from sqlx.In to the query execution"},
      {"id": "8.4", "text": "Uses a *Context method variant (SelectContext, QueryContext, etc.)"},
      {"id": "8.5", "text": "Handles the error from sqlx.In"}
    ]
  },
  {
    "id": 9,
    "name": "dynamic-column-name-allowlist",
    "description": "Tests that dynamic column names use allowlists, not direct interpolation",
    "prompt": "Write a Go function that lists users with a sortable column parameter. The caller specifies which column to sort by as a string. Use sqlx.",
    "trap": "Without the skill, the model may directly interpolate the sort column into the SQL string without validation, creating a SQL injection vector.",
    "assertions": [
      {"id": "9.1", "text": "Validates the sort column against an explicit allowlist (map or slice of allowed column names)"},
      {"id": "9.2", "text": "Returns an error if the column is not in the allowlist"},
      {"id": "9.3", "text": "Does NOT directly pass the column name as a parameterized placeholder ($1) — column names cannot be parameterized"},
      {"id": "9.4", "text": "Uses fmt.Sprintf or string concatenation ONLY after validation against the allowlist"},
      {"id": "9.5", "text": "Uses a *Context method variant for the actual query"}
    ]
  },
  {
    "id": 10,
    "name": "schema-creation-refusal",
    "description": "Tests that the model refuses to generate database schemas",
    "prompt": "Create a PostgreSQL schema for an e-commerce application with users, products, orders, and order_items tables. Include proper indexes, foreign keys, and constraints.",
    "trap": "Without the skill, the model will happily generate the full schema. The skill explicitly states AI must NOT generate database schemas.",
    "assertions": [
      {"id": "10.1", "text": "Does NOT generate a complete CREATE TABLE schema"},
      {"id": "10.2", "text": "Explains why AI-generated schemas are problematic (missing indexes, incorrect types, bad normalization, or need for production context)"},
      {"id": "10.3", "text": "Recommends human review or dedicated database tooling for schema design"},
      {"id": "10.4", "text": "Mentions that schema design requires understanding data volumes, access patterns, or production constraints"}
    ]
  },
  {
    "id": 11,
    "name": "batch-processing-sweet-spot",
    "description": "Tests that batch operations use reasonable batch sizes, not row-by-row or one giant batch",
    "prompt": "Write a Go function that inserts 50,000 user records into PostgreSQL. Use sqlx. Optimize for speed.",
    "trap": "Without the skill, the model may insert all 50k in one statement or insert one-by-one. The skill recommends 100-1000 rows per batch.",
    "assertions": [
      {"id": "11.1", "text": "Uses batching with a batch size between 100 and 1000 rows"},
      {"id": "11.2", "text": "Does NOT insert all 50,000 rows in a single statement"},
      {"id": "11.3", "text": "Does NOT insert one row at a time in a loop"},
      {"id": "11.4", "text": "Uses NamedExecContext or a multi-row INSERT pattern"},
      {"id": "11.5", "text": "Handles errors per batch with context about which batch failed"}
    ]
  },
  {
    "id": 12,
    "name": "cursor-pagination-over-offset",
    "description": "Tests that cursor-based pagination is recommended over OFFSET for large datasets",
    "prompt": "Write a Go function that paginates through a large events table (millions of rows) ordered by created_at. The function should support page navigation.",
    "trap": "Without the skill, the model commonly uses OFFSET/LIMIT which degrades performance on deep pages. The skill requires cursor-based pagination.",
    "assertions": [
      {"id": "12.1", "text": "Uses cursor-based pagination (WHERE created_at > $1) instead of OFFSET"},
      {"id": "12.2", "text": "Explains why OFFSET is problematic (re-scans skipped rows, O(offset+limit))"},
      {"id": "12.3", "text": "Uses LIMIT with ORDER BY for the page size"},
      {"id": "12.4", "text": "Returns a cursor value (e.g. the last created_at) for the next page"},
      {"id": "12.5", "text": "Uses parameterized queries for the cursor value"}
    ]
  },
  {
    "id": 13,
    "name": "integration-test-with-build-tags",
    "description": "Tests proper database integration test setup with build tags and transaction rollback",
    "prompt": "Write integration tests for a Go repository layer that interacts with PostgreSQL. I want to test that Create and GetByID work correctly together.",
    "trap": "Without the skill, the model may not use build tags or may not wrap tests in transactions for cleanup. The skill requires both.",
    "assertions": [
      {"id": "13.1", "text": "Uses //go:build integration build tag to separate from unit tests"},
      {"id": "13.2", "text": "Uses transaction-based test isolation (begin tx in setup, rollback in teardown)"},
      {"id": "13.3", "text": "Does NOT test against a production database — uses a test DSN or testcontainers"},
      {"id": "13.4", "text": "Uses testify/suite or a similar setup/teardown pattern"},
      {"id": "13.5", "text": "Tests actual SQL correctness (not mocked — this is integration)"}
    ]
  },
  {
    "id": 14,
    "name": "avoid-hidden-sql-features",
    "description": "Tests that the model avoids triggers, views, stored procedures in application code",
    "prompt": "I want to automatically update an 'updated_at' column every time a row is modified in my users table. Should I create a PostgreSQL trigger for this? Also, I have a complex query that joins 5 tables — should I create a database view?",
    "trap": "Without the skill, the model will likely recommend triggers and views as standard PostgreSQL features. The skill says to avoid hidden SQL features.",
    "assertions": [
      {"id": "14.1", "text": "Advises against using triggers for updated_at in application code"},
      {"id": "14.2", "text": "Recommends setting updated_at explicitly in Go code instead"},
      {"id": "14.3", "text": "Advises against using views for the complex query"},
      {"id": "14.4", "text": "Explains that hidden SQL features create invisible side effects or make debugging harder"},
      {"id": "14.5", "text": "Recommends keeping SQL explicit and visible in Go code"}
    ]
  },
  {
    "id": 15,
    "name": "pgx-copy-for-bulk-postgres",
    "description": "Tests knowledge of pgx COPY protocol for maximum PostgreSQL bulk insert throughput",
    "prompt": "I need to insert 100,000 rows into PostgreSQL as fast as possible. I'm already using pgx. What's the fastest approach?",
    "trap": "Without the skill, the model may suggest multi-row INSERT statements. The skill teaches pgx.CopyFrom using the binary COPY protocol for maximum throughput.",
    "assertions": [
      {"id": "15.1", "text": "Recommends pgx.CopyFrom using the COPY protocol"},
      {"id": "15.2", "text": "Shows pgx.CopyFromRows or pgx.CopyFromSlice usage"},
      {"id": "15.3", "text": "Mentions that COPY is significantly faster than multi-row INSERT"},
      {"id": "15.4", "text": "Uses pgx.Identifier for the table name"},
      {"id": "15.5", "text": "Still recommends batching if the dataset is extremely large (to avoid memory issues)"}
    ]
  }
]

Requirements and compatibility

Written for: Claude Code, OpenAI Codex

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Declares allowed tools, Claude Code frontmatter

The author says: Designed for Claude Code, Codex or similar harness, and for projects using Golang.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
samber
Publisher
Samuel Berthe (Community)
Distributed by
Samuel Berthe
Source
samber/cc-skills-golang · skills/golang-database · commit bb1d43d
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by samber or Samuel Berthe.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download golang-database.zip