Skip to content


Repository files navigation

🚀 GocqlX GoDoc Go Report Card Build Status

GocqlX makes working with Scylla easy and less error-prone. It’s inspired by Sqlx, a tool for working with SQL databases, but it goes beyond what Sqlx provides.


  • Binding query parameters from struct fields, map, or both
  • Scanning query results into structs based on field names
  • Convenient functions for common tasks such as loading a single row into a struct or all rows into a slice (list) of structs
  • Making any struct a UDT without implementing marshalling functions
  • GocqlX is fast. Its performance is comparable to raw driver. You can find some benchmarks here.

Subpackages provide additional functionality:


    go get -u

Getting started

Wrap gocql Session:

// Create gocql cluster.
cluster := gocql.NewCluster(hosts...)
// Wrap session on creation, gocqlx session embeds gocql.Session pointer. 
session, err := gocqlx.WrapSession(cluster.CreateSession())
if err != nil {

Specify table model:

// metadata specifies table name and columns it must be in sync with schema.
var personMetadata = table.Metadata{
	Name:    "person",
	Columns: []string{"first_name", "last_name", "email"},
	PartKey: []string{"first_name"},
	SortKey: []string{"last_name"},

// personTable allows for simple CRUD operations based on personMetadata.
var personTable = table.New(personMetadata)

// Person represents a row in person table.
// Field names are converted to snake case by default, no need to add special tags.
// A field will not be persisted by adding the `db:"-"` tag or making it unexported.
type Person struct {
	FirstName string
	LastName  string
	Email     []string
	HairColor string `db:"-"`  // exported and skipped
	eyeColor  string           // unexported also skipped

Bind data from a struct and insert a row:

p := Person{
	"red",    // not persisted
	"hazel"   // not persisted
q := session.Query(personTable.Insert()).BindStruct(p)
if err := q.ExecRelease(); err != nil {

Load a single row to a struct:

p := Person{
	nil, // no email
q := session.Query(personTable.Get()).BindStruct(p)
if err := q.GetRelease(&p); err != nil {
// stdout: {Michał Matczuk []}

Load all rows in to a slice:

var people []Person
q := session.Query(personTable.Select()).BindMap(qb.M{"first_name": "Michał"})
if err := q.SelectRelease(&people); err != nil {
// stdout: [{Michał Matczuk []}]

Generating table metadata with schemagen


go get -u ""


$GOBIN/schemagen [flags]

  -cluster string
    	a comma-separated list of host:port tuples (default "")
  -keyspace string
    	keyspace to inspect (required)
  -output string
    	the name of the folder to output to (default "models")
  -pkgname string
    	the name you wish to assign to your generated package (default "models") 


Running the following command for examples keyspace:

$GOBIN/schemagen -cluster="" -keyspace="examples" -output="models" -pkgname="models"

Generates models/models.go as follows:

// Code generated by "gocqlx/cmd/schemagen"; DO NOT EDIT.

package models

import ""

// Table models.
var (
	Playlists = table.New(table.Metadata{
		Name: "playlists",
		Columns: []string{
		PartKey: []string{
		SortKey: []string{

	Songs = table.New(table.Metadata{
		Name: "songs",
		Columns: []string{
		PartKey: []string{
		SortKey: []string{},


You can find lots of examples in example_test.go.

Go and run them locally:

make run-scylla
make run-examples


GocqlX performance is comparable to the raw gocql driver. Below benchmark results running on my laptop.

BenchmarkBaseGocqlInsert            2392            427491 ns/op            7804 B/op         39 allocs/op
BenchmarkGocqlxInsert               2479            435995 ns/op            7803 B/op         39 allocs/op
BenchmarkBaseGocqlGet               2853            452384 ns/op            7309 B/op         35 allocs/op
BenchmarkGocqlxGet                  2706            442645 ns/op            7646 B/op         38 allocs/op
BenchmarkBaseGocqlSelect             747           1664365 ns/op           49415 B/op        927 allocs/op
BenchmarkGocqlxSelect                667           1877859 ns/op           42521 B/op        932 allocs/op

See the benchmark in benchmark_test.go.


Copyright (C) 2017 ScyllaDB

This project is distributed under the Apache 2.0 license. See the LICENSE file for details. It contains software from:

Apache®, Apache Cassandra® are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries. No endorsement by The Apache Software Foundation is implied by the use of these marks.

GitHub star is always appreciated!