Skip to main content
Hand-written column lists are tedious to maintain and tend to drift out of sync with your models. The csql/qb package derives SQL fragments from your models’ db: tags, so your queries stay correct as the struct changes. Throughout this page, let’s assume we have the following model:

Inserts

qb.Columns renders the column list, qb.ValuePlaceholders the matching ?s, and qb.Values the arguments:
This renders INSERT INTO rockets (id, created_at, name, fuel) VALUES (?, ?, ?, ?).

Selects

qb.Columns also works on a zero value, which is handy for SELECT statements:
For joined queries, you may pass a table alias; qb.Columns(Rocket{}, "r") renders r.id, r.created_at, r.name, r.fuel.

Updates and readonly

qb.SetColumns and qb.SetValues render SET clauses, and this is where the ,readonly tag modifier earns its keep. Columns marked readonly, such as id and created_at, are included in inserts but excluded from updates:
This renders UPDATE rockets SET name = ?, fuel = ? WHERE id = ?. The readonly columns never appear.

Upserts

qb.ValuesAndSetValues returns the insert values followed by the update values, which lines up exactly with an upsert:
All of the functions above follow the same tag rules: untagged, db:"-", and unexported fields are skipped, while embedded structs are flattened recursively. To learn more, see Models.