{"id":13412133,"url":"https://github.com/arthurkushman/buildsqlx","last_synced_at":"2026-01-12T07:57:00.250Z","repository":{"id":41338487,"uuid":"202977599","full_name":"arthurkushman/buildsqlx","owner":"arthurkushman","description":"Go database query builder library for PostgreSQL","archived":false,"fork":false,"pushed_at":"2024-04-21T19:00:15.000Z","size":231,"stargazers_count":169,"open_issues_count":7,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-11T18:32:47.507Z","etag":null,"topics":["active-record","clauses","database-table","ddl","dml","go","golang","golang-library","postgresql","query-builder","sql","sqlbuilder","transactions"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arthurkushman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-18T08:18:21.000Z","updated_at":"2024-10-09T14:00:21.000Z","dependencies_parsed_at":"2022-08-15T17:31:37.388Z","dependency_job_id":"8f18c553-4f69-4bec-978c-aa6d7908da83","html_url":"https://github.com/arthurkushman/buildsqlx","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurkushman%2Fbuildsqlx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurkushman%2Fbuildsqlx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurkushman%2Fbuildsqlx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurkushman%2Fbuildsqlx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arthurkushman","download_url":"https://codeload.github.com/arthurkushman/buildsqlx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230374126,"owners_count":18216042,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["active-record","clauses","database-table","ddl","dml","go","golang","golang-library","postgresql","query-builder","sql","sqlbuilder","transactions"],"created_at":"2024-07-30T20:01:21.359Z","updated_at":"2026-01-12T07:57:00.240Z","avatar_url":"https://github.com/arthurkushman.png","language":"Go","readme":"# buildsqlx\n\nGo Database query builder\nlibrary [![Tweet](http://jpillora.com/github-twitter-button/img/tweet.png)](https://twitter.com/intent/tweet?text=Go%20database%20query%20builder%20library%20\u0026url=https://github.com/arthurkushman/buildsqlx\u0026hashtags=go,golang,sql,builder,postgresql,sql-builder,developers)\n\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\n[![Go Report Card](https://goreportcard.com/badge/github.com/arthurkushman/buildsqlx)](https://goreportcard.com/report/github.com/arthurkushman/buildsqlx)\n[![Build and run](https://github.com/arthurkushman/buildsqlx/workflows/Build%20and%20run/badge.svg)](https://github.com/arthurkushman/buildsqlx/actions)\n[![GoDoc](https://github.com/golang/gddo/blob/c782c79e0a3c3282dacdaaebeff9e6fd99cb2919/gddo-server/assets/status.svg)](https://godoc.org/github.com/arthurkushman/buildsqlx)\n[![codecov](https://codecov.io/gh/arthurkushman/buildsqlx/branch/master/graph/badge.svg)](https://codecov.io/gh/arthurkushman/buildsqlx)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n* [Installation](#user-content-installation)\n* [Selects, Ordering, Limit \u0026 Offset](#user-content-selects-ordering-limit--offset)\n* [GroupBy / Having](#user-content-groupby--having)\n* [Where, AndWhere, OrWhere clauses](#user-content-where-andwhere-orwhere-clauses)\n* [WhereIn / WhereNotIn](#user-content-wherein--wherenotin)\n* [WhereNull / WhereNotNull](#user-content-wherenull--wherenotnull)\n* [Left / Right / Cross / Inner / Left Outer Joins](#user-content-left--right--cross--inner--left-outer-joins)\n* [Inserts](#user-content-inserts)\n* [Updates](#user-content-updates)\n* [Delete](#user-content-delete)\n* [Drop, Truncate, Rename](#user-content-drop-truncate-rename)\n* [Increment \u0026 Decrement](#user-content-increment--decrement)\n* [Union / Union All](#user-content-union--union-all)\n* [Transaction mode](#user-content-transaction-mode)\n* [Dump, Dd](#user-content-dump-dd)\n* [Check if table exists](#user-content-check-if-table-exists)\n* [Check if columns exist in a table within schema](#user-content-check-if-columns-exist-in-a-table-within-schema)\n* [Retrieving A Single Row / Column From A Table](#user-content-retrieving-a-single-row--column-from-a-table)\n* [WhereExists / WhereNotExists](#user-content-whereexists--wherenotexists)\n* [Determining If Records Exist](#user-content-determining-if-records-exist)\n* [Aggregates](#user-content-aggregates)\n* [Create table](#user-content-create-table)\n* [Add / Modify / Drop columns](#user-content-add--modify--drop-columns)\n* [Chunking Results](#user-content-chunking-results)\n* [Pluck / PluckMap](#user-content-pluck--pluckmap)\n\n## Installation\n\n```bash\ngo get -u github.com/arthurkushman/buildsqlx\n```\n\n## Selects, Ordering, Limit \u0026 Offset\n\nYou may not always want to select all columns from a database table. Using the select method, you can specify a custom\nselect clause for the query:\n\n```go\npackage yourpackage\n\nimport (\n\t\"database/sql\"\n\n\t\"github.com/arthurkushman/buildsqlx\"\n\t_ \"github.com/lib/pq\"\n)\n\nvar db = buildsqlx.NewDb(buildsqlx.NewConnection(\"postgres\", \"user=postgres dbname=postgres password=postgres sslmode=disable\"))\n\nfunc main() {\n\tqDb := db.Table(\"posts\").Select(\"title\", \"body\")\n\n\ttype DataStruct struct {\n\t\tFoo string\n\t\tBar string\n\t\tBaz *int64\n\t}\n\n\tdataStruct := DataStruct{}\n\tvar testStructs []DataStruct\n\t// If you already have a query builder instance and you wish to add a column to its existing select clause, you may use the addSelect method:\n\terr := qDb.AddSelect(\"points\").GroupBy(\"topic\").OrderBy(\"points\", \"DESC\").Limit(15).Offset(5).EachToStruct(func(rows *sql.Rows) error {\n\t\terr = db.Next(rows, \u0026dataStruct)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\ttestStructs = append(testStructs, dataStruct)\n\t\treturn nil\n\t})\n}\n```\n\n### InRandomOrder\n\n```go\nerr = db.Table(\"users\").Select(\"name\", \"post\", \"user_id\").InRandomOrder().ScanStruct(dataStruct)\n```\n\n## GroupBy / Having\n\nThe `GroupBy` and `Having` methods may be used to group the query results.\nThe having method's signature is similar to that of the `Where` method:\n\n```go\nerr = db.table(\"users\").GroupBy(\"account_id\").Having(\"account_id\", \"\u003e\", 100).ScanStruct(dataStruct)\n```\n\n## Where, AndWhere, OrWhere clauses\n\nYou may use the `Where` method on a query builder instance to add where clauses to the query.\nThe most basic call to where requires three arguments.\nThe first argument is the name of the column.\nThe second argument is an operator, which can be any of the database's supported operators.\nFinally, the third argument is the value to evaluate against the column.\n\n```go\nerr = db.Table(\"table1\").Select(\"foo\", \"bar\", \"baz\").Where(\"foo\", \"=\", cmp).AndWhere(\"bar\", \"!=\", \"foo\").OrWhere(\"baz\", \"=\", 123)..ScanStruct(dataStruct)\n```\n\nYou may chain where constraints together as well as add or clauses to the query.\nThe `OrWhere` method accepts the same arguments as the `Where` method.\n\n## WhereIn / WhereNotIn\n\nThe `WhereIn` method verifies that a given column's value is contained within the given slice:\n\n```go\nerr = db.Table(\"table1\").WhereIn(\"id\", []int64{1, 2, 3}).OrWhereIn(\"name\", []string{\"John\", \"Paul\"}).ScanStruct(dataStruct)\n```\n\n## WhereNull / WhereNotNull\n\nThe `WhereNull` method verifies that the value of the given column is `NULL`:\n\n```go\nerr = db.Table(\"posts\").WhereNull(\"points\").OrWhereNotNull(\"title\")..ScanStruct(dataStruct)\n```\n\n## Left / Right / Cross / Inner / Left Outer Joins\n\nThe query builder may also be used to write join statements.\nTo perform a basic \"inner join\", you may use the `InnerJoin` method on a query builder instance.\nThe first argument passed to the join method is the name of the table you need to join to,\nwhile the remaining arguments specify the column constraints for the join.\nYou can even join to multiple tables in a single query:\n\n```go\nerr = db.Table(\"users\").Select(\"name\", \"post\", \"user_id\").LeftJoin(\"posts\", \"users.id\", \"=\", \"posts.user_id\").EachToStruct(func(rows *sql.Rows) error {\n    err = db.Next(rows, \u0026dataStruct)\n    if err != nil {\n        return err\n    }\n    \n    testStructs = append(testStructs, dataStruct)\n    return nil\n})\n```\n\n## Inserts\n\nThe query builder also provides an `Insert` method for inserting records into the database table.\nThe `Insert/InsertBatch` methods accept a structure (or slice of structs) of column names and values:\n\n```go\n// insert without getting id\nerr = db.Table(\"table1\").Insert(DataStruct{\n    Foo: \"foo foo foo\",\n    Bar: \"bar bar bar\",\n    Baz: \u0026baz,\n})\n\n// insert returning id\nid, err := db.Table(\"table1\").InsertGetId(DataStruct{\n    Foo: \"foo foo foo\",\n    Bar: \"bar bar bar\",\n    Baz: \u0026baz,\n})\n\n// batch insert \nerr = db.Table(\"table1\").InsertBatch([]DataStruct{\n    {Foo: \"foo foo foo\", Bar: \"bar bar bar\", Baz: \u0026baz},\n    {Foo: \"foo foo foo foo\", Bar: \"bar bar bar bar\", Baz: \u0026baz},\n    {Foo: \"foo foo foo foo foo\", Bar: \"bar bar bar bar bar\", Baz: \u0026baz},\n})\n```\n\n## Updates\n\nIn addition to inserting records into the database,\nthe query builder can also update existing records using the update method.\nThe update method, like the insert method, accepts a slice of column and value pairs containing the columns to be\nupdated.\nYou may constrain the update query using where clauses:\n\n```go\nrows, err := db.Table(\"posts\").Where(\"points\", \"\u003e\", 3).Update(DataStruct{\n    Title: \"awesome\",\n})\n```\n\n## Delete\n\nThe query builder may also be used to delete records from the table via the delete method.\nYou may constrain delete statements by adding where clauses before calling the delete method:\n\n```go\nrows, err := db.Table(\"posts\").Where(\"points\", \"=\", 123).Delete()\n```\n\n## Drop, Truncate, Rename\n\n```go\ndb.Drop(\"table_name\")\n\ndb.DropIfExists(\"table_name\")\n\ndb.Truncate(\"table_name\")\n\ndb.Rename(\"table_name1\", \"table_name2\")\n```\n\n## Increment \u0026 Decrement\n\nThe query builder also provides convenient methods for incrementing or decrementing the value of a given column.\nThis is a shortcut, providing a more expressive and terse interface compared to manually writing the update statement.\n\nBoth of these methods accept 2 arguments: the column to modify, a second argument to control the amount by which the\ncolumn should be incremented or decremented:\n\n```go\ndb.Table(\"users\").Increment(\"votes\", 3)\n\ndb.Table(\"users\").Decrement(\"votes\", 1)\n```\n\n## Union / Union All\n\nThe query builder also provides a quick way to \"union\" two queries together.\nFor example, you may create an initial query and use the union method to union it with a second query:\n\n```go\nunion := db.Table(\"posts\").Select(\"title\", \"likes\").Union()\nres, err := union.Table(\"users\").Select(\"name\", \"points\").ScanStruct(dataStruct)\n\n// or if UNION ALL is of need\n// union := db.Table(\"posts\").Select(\"title\", \"likes\").UnionAll()\n```\n\n## Transaction mode\n\nYou can run arbitrary queries mixed with any code in transaction mode getting an error and as a result rollback if\nsomething went wrong\nor committed if everything is ok:\n\n```go\nerr := db.InTransaction(func () (interface{}, error) {\n    return db.Table(\"users\").Select(\"name\", \"post\", \"user_id\").ScanStruct(dataStruct)\n})\n```\n\n## Dump, Dd\n\nYou may use the Dd or Dump methods while building a query to dump the query bindings and SQL.\nThe dd method will display the debug information and then stop executing the request.\nThe dump method will display the debug information but allow the request to keep executing:\n\n```go\n\t// to print raw sql query to stdout \n\tdb.Table(\"table_name\").Select(\"foo\", \"bar\", \"baz\").Where(\"foo\", \"=\", cmp).AndWhere(\"bar\", \"!=\", \"foo\").Dump()\n\n\t// or to print to stdout and exit a.k.a dump and die\n\tdb.Table(\"table_name\").Select(\"foo\", \"bar\", \"baz\").Where(\"foo\", \"=\", cmp).AndWhere(\"bar\", \"!=\", \"foo\").Dd()\n```\n\n## Check if table exists\n\n```go\ntblExists, err := db.HasTable(\"public\", \"posts\")\n```\n\n## Check if columns exist in a table within schema\n\n```go\ncolsExists, err := db.HasColumns(\"public\", \"posts\", \"title\", \"user_id\")\n```\n\n## Retrieving A Single Row / Column From A Table\n\nIf you just need to retrieve a single row from the database table, you may use the `First` func.\nThis method will return a single `map[string]interface{}`:\n\n```go\nerr = db.Table(\"posts\").Select(\"title\").OrderBy(\"created_at\", \"desc\").First(dataStruct)\n\n// usage ex: dataStruct.Title\n```\n\nIf you don't even need an entire row, you may extract a single value from a record using the `Value` method.\nThis method will return the value of the column directly:\n\n```go\nerr = db.Table(\"users\").OrderBy(\"points\", \"desc\").Value(dataStruct, \"name\")\n\n// dataStruct.Name -\u003e \"Alex Shmidt\"\n```\n\nTo retrieve a single row by its id column value, use the `find` method:\n\n```go\nuser, err := db.Table(\"users\").Find(dataStruct, id)\n\n// dataStruct.ID, dataStruct.Name, dataStruct.Email etc\n```\n\n## WhereExists / WhereNotExists\n\nThe whereExists method allows you to write where exists SQL clauses.\nThe whereExists method accepts a *DB argument,\nwhich will receive a query builder instance allowing you to define the query that should be placed inside the \"exists\" clause:\n\n```go\nerr = db.Table(\"users\").Select(\"name\").WhereExists(\n    db.Table(\"users\").Select(\"name\").Where(\"points\", \"\u003e=\", int64(12345)),\n).First(dataStruct)\n```\n\nAny query that is of need to build one can place inside `WhereExists` clause/func.\n\n## WhereBetween / WhereNotBetween\n\nThe whereBetween func verifies that a column's value is between two values:\n\n```go\nerr = db.Table(UsersTable).Select(\"name\").WhereBetween(\"points\", 1233, 12345).ScanStruct(\u0026testStruct)\n```\n\nThe whereNotBetween func verifies that a column's value lies outside of two values:\n\n```go\nerr = db.Table(UsersTable).Select(\"name\").WhereNotBetween(\"points\", 123, 123456).ScanStruct(\u0026testStruct)\n```\n\n## Determining If Records Exist\n\nInstead of using the `Count` method to determine if any records exist that match your query's constraints,\nyou may use the exists and doesntExist methods:\n\n```go\nexists, err := db.Table(UsersTable).Select(\"name\").Where(\"points\", \"\u003e=\", int64(12345)).Exists()\n// use an inverse DoesntExists() if needed\n```\n\n## Aggregates\n\nThe query builder also provides a variety of aggregate methods such as Count, Max, Min, Avg, and Sum.\nYou may call any of these methods after constructing your query:\n\n```go\ncnt, err := db.Table(UsersTable).WHere(\"points\", \"\u003e=\", 1234).Count()\n\navg, err := db.Table(UsersTable).Avg(\"points\")\n\nmx, err := db.Table(UsersTable).Max(\"points\")\n\nmn, err := db.Table(UsersTable).Min(\"points\")\n\nsum, err := db.Table(UsersTable).Sum(\"points\")\n```\n\n## Create table\n\nTo create a new database table, use the CreateTable method.\nThe Schema method accepts two arguments.\nThe first is the name of the table, while the second is an anonymous function/closure which receives a Table struct that\nmay be used to define the new table:\n\n```go\nres, err := db.Schema(\"big_tbl\", func(table *Table) error {\n    table.Increments(\"id\")\n    table.String(\"title\", 128).Default(\"The quick brown fox jumped over the lazy dog\").Unique(\"idx_ttl\")\n    table.SmallInt(\"cnt\").Default(1)\n    table.Integer(\"points\").NotNull()\n    table.BigInt(\"likes\").Index(\"idx_likes\")\n    table.Text(\"comment\").Comment(\"user comment\").Collation(\"de_DE\")\n    table.DblPrecision(\"likes_to_points\").Default(0.0)\n    table.Char(\"tag\", 10)\n    table.DateTime(\"created_at\", true)\n    table.DateTimeTz(\"updated_at\", true)\n    table.Decimal(\"tax\", 2, 2)\n    table.TsVector(\"body\")\n    table.TsQuery(\"body_query\")\n    table.Jsonb(\"settings\")\n    table.Point(\"pt\")\n    table.Polygon(\"poly\")\n    table.TableComment(\"big table for big data\")\n    \n    return nil\n})\n\n// to make a foreign key constraint from another table\n_, err = db.Schema(\"tbl_to_ref\", func (table *Table) error {\n    table.Increments(\"id\")\n    table.Integer(\"big_tbl_id\").ForeignKey(\"fk_idx_big_tbl_id\", \"big_tbl\", \"id\").Concurrently().IfNotExists()\n    // to add index on existing column just repeat stmt + index e.g.:\n    table.Char(\"tag\", 10).Index(\"idx_tag\").Include(\"likes\", \"created_at\")\n    table.Rename(\"settings\", \"options\")\n    \n    return nil\n})    \n```\n\n## Add / Modify / Drop columns\n\nThe Table structure in the Schema's 2nd argument may be used to update existing tables. Just the way you've been created\nit.\nThe Change method allows you to modify some existing column types to a new type or modify the column's attributes.\n\n```go\nres, err := db.Schema(\"tbl_name\", func(table *Table) error {\n    table.String(\"title\", 128).Change()\n    \n    return nil\n})\n```\n\nUse DropColumn method to remove any column:\n\n```go\nres, err := db.Schema(\"tbl_name\", func(table *Table) error {\n    table.DropColumn(\"deleted_at\").IfExists()\n    // To drop an index on the column    \n    table.DropIndex(\"idx_title\")\n    \n    return nil\n})\n```\n\n## Chunking Results\n\nIf you need to work with thousands of database records, consider using the chunk method.\nThis method retrieves a small chunk of the results at a time and feeds each chunk into a closure for processing.\n\n```go\nvar sumOfPoints int64\ndataStruct := \u0026DataStructUser{}\nerr = db.Table(UsersTable).Select(\"name\", \"points\").Chunk(dataStruct, 100, func(users []any) bool {\n    for _, v := range users {\n        user := v.(DataStructUser) \n        // your code goes here e.g.:\n        sumOfPoints += user.Points\n    }\n\t\n    // or you can return false here to stop running chunks \n    return true\n})\n```\n\n## Pluck / PluckMap\n\nIf you would like to get values of a particular column(s) of a struct and place them into slice - use `Pluck` method:\n```go\n    dataStruct := \u0026DataStructUser{}\n    res, err := db.Table(UsersTable).Pluck(dataStruct)\n    for k, v := range res {\n        val := v.(DataStructUser)\n        fmt.Println(val.Name) // f.e.: Alex Shmidt\n    }\n\t\n    // or use a PluckMap method to aggregate key/value pairs to a map\n    res, err := db.Table(UsersTable).PluckMap(dataStruct, \"name\", \"points\")\n    for k, m := range res {\n        for key, value := range m {\n            keyVal := key.(string)\n            valueVal := value.(DataStructUser) \n            // rest of the code ...\n        }\n    }\n```\n\nPS Why use buildsqlx? Because it is simple and fast, yet versatile. The builder code-style has been inherited from greatest web-frameworks, so u can easily query anything from db. \n\nSupporters gratitude:\n\n\u003cimg src=\"https://github.com/SoliDry/laravel-api/blob/master/tests/images/jetbrains-logo.png\" alt=\"JetBrains logo\" width=\"200\" height=\"166\" /\u003e","funding_links":[],"categories":["Database","Uncategorized","数据库  `go语言实现的数据库`","Generators","数据库","Data Integration Frameworks"],"sub_categories":["SQL Query Builders","SQL 查询语句构建库","Advanced Console UIs","SQL查询生成器"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farthurkushman%2Fbuildsqlx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farthurkushman%2Fbuildsqlx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farthurkushman%2Fbuildsqlx/lists"}