{"id":33278689,"url":"https://github.com/drone/sqlgen","last_synced_at":"2025-11-22T04:02:00.343Z","repository":{"id":57480986,"uuid":"42339567","full_name":"drone/sqlgen","owner":"drone","description":"Go tool for generating sql scanners, sql statements and other helper functions","archived":true,"fork":false,"pushed_at":"2016-06-14T05:10:53.000Z","size":275,"stargazers_count":184,"open_issues_count":7,"forks_count":24,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-08-13T17:10:32.713Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drone.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-12T01:17:44.000Z","updated_at":"2025-08-04T06:50:27.000Z","dependencies_parsed_at":"2022-09-26T17:41:22.441Z","dependency_job_id":null,"html_url":"https://github.com/drone/sqlgen","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/drone/sqlgen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drone%2Fsqlgen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drone%2Fsqlgen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drone%2Fsqlgen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drone%2Fsqlgen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drone","download_url":"https://codeload.github.com/drone/sqlgen/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drone%2Fsqlgen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285731803,"owners_count":27222214,"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","status":"online","status_checked_at":"2025-11-22T02:00:05.934Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-11-17T10:00:42.822Z","updated_at":"2025-11-22T04:02:00.332Z","avatar_url":"https://github.com/drone.png","language":"Go","readme":"**sqlgen** generates SQL statements and database helper functions from your Go structs. It can be used in place of a simple ORM or hand-written SQL. See the [demo](https://github.com/drone/sqlgen/tree/master/demo) directory for examples.\n\n### Install\n\nInstall or upgrade with this command:\n\n```\ngo get -u github.com/drone/sqlgen\n```\n\n### Usage\n\n```\nUsage of sqlgen:\n  -type string\n    \ttype to generate; required\n  -file string\n    \tinput file name; required\n  -o string\n    \toutput file name\n  -pkg string\n    \toutput package name\n  -db string\n    \tsql dialect; sqlite, postgres, mysql\n  -schema\n    \tgenerate sql schema and queries; default true\n  -funcs\n    \tgenerate sql helper functions; default true\n```\n\n### Tutorial\n\nFirst, let's start with a simple `User` struct in `user.go`:\n\n```Go\ntype User struct {\n\tID     int64\n\tLogin  string\n\tEmail  string\n}\n```\n\nWe can run the following command:\n\n```\nsqlgen -file user.go -type User -pkg demo\n```\n\nThe tool outputs the following generated code:\n\n```Go\nfunc ScanUser(row *sql.Row) (*User, error) {\n\tvar v0 int64\n\tvar v1 string\n\tvar v2 string\n\n\terr := row.Scan(\n\t\t\u0026v0,\n\t\t\u0026v1,\n\t\t\u0026v2,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tv := \u0026User{}\n\tv.ID = v0\n\tv.Login = v1\n\tv.Email = v2\n\n\treturn v, nil\n}\n\nconst CreateUserStmt = `\nCREATE TABLE IF NOT EXISTS users (\n user_id     INTEGER\n,user_login  TEXT\n,user_email  TEXT\n);\n`\n\nconst SelectUserStmt = `\nSELECT \n user_id\n,user_login\n,user_email\nFROM users \n`\n\nconst SelectUserRangeStmt = `\nSELECT \n user_id\n,user_login\n,user_email\nFROM users \nLIMIT ? OFFSET ?\n`\n\n\n// more functions and sql statements not displayed\n```\n\nThis is a great start, but what if we want to specify primary keys, column sizes and more? This may be acheived by annotating your code using Go tags. For example, we can tag the `ID` field to indicate it is a primary key and will auto increment:\n\n```diff\ntype User struct {\n-   ID      int64\n+   ID      int64  `sql:\"pk: true, auto: true\"`\n    Login   string\n    Email   string\n}\n```\n\nThis information allows the tool to generate smarter SQL statements:\n\n```diff\nCREATE TABLE IF NOT EXISTS users (\n-user_id     INTEGER\n+user_id     INTEGER PRIMARY KEY AUTOINCREMENT\n,user_login  TEXT\n,user_email  TEXT\n);\n```\n\nIncluding SQL statements to select, insert, update and delete data using the primary key:\n\n```Go\nconst SelectUserPkeyStmt = `\nSELECT \n user_id\n,user_login\n,user_email\nWHERE user_id=?\n`\n\nconst UpdateUserPkeyStmt = `\nUPDATE users SET \n user_id=?\n,user_login=?\n,user_email=?\nWHERE user_id=?\n`\n\nconst DeleteUserPkeyStmt = `\nDELETE FROM users \nWHERE user_id=?\n`\n```\n\nWe can take this one step further and annotate indexes. In our example, we probably want to make sure the `user_login` field has a unique index:\n\n```diff\ntype User struct {\n    ID      int64  `sql:\"pk: true, auto: true\"`\n-   Login   string\n+   Login   string `sql:\"unique: user_login\"`\n    Email   string\n}\n```\n\nThis information instructs the tool to generate the following:\n\n\n```Go\nconst CreateUserLogin = `\nCREATE UNIQUE INDEX IF NOT EXISTS user_login ON users (user_login)\n```\n\nThe tool also assumes that we probably intend to fetch data from the database using this index. The tool will therefore automatically generate the following queries:\n\n```Go\nconst SelectUserLoginStmt = `\nSELECT \n user_id\n,user_login\n,user_email\nWHERE user_login=?\n`\n\nconst UpdateUserLoginStmt = `\nUPDATE users SET \n user_id=?\n,user_login=?\n,user_email=?\nWHERE user_login=?\n`\n\nconst DeleteUserLoginStmt = `\nDELETE FROM users \nWHERE user_login=?\n`\n```\n\n### Nesting\n\nNested Go structures can be flattened into a single database table. As an example, we have a `User` and `Address` with a one-to-one relationship. In some cases, we may prefer to de-normalize our data and store in a single table, avoiding un-necessary joins.\n\n```diff\ntype User struct {\n    ID     int64  `sql:\"pk: true\"`\n    Login  string\n    Email  string\n+   Addr   *Address\n}\n\ntype Address struct {\n    City   string\n    State  string\n    Zip    string `sql:\"index: user_zip\"`\n}\n```\n\nThe above relationship is flattened into a single table (see below). When the data is retrieved from the database the nested structure is restored.\n\n```sql\nCREATE TALBE IF NOT EXISTS users (\n user_id         INTEGER PRIMARY KEY AUTO_INCREMENT\n,user_login      TEXT\n,user_email      TEXT\n,user_addr_city  TEXT\n,user_addr_state TEXT\n,user_addr_zip   TEXT\n);\n```\n\n### JSON Encoding\n\nSome types in your struct may not have native equivalents in your database such as `[]string`. These values can be marshaled and stored as JSON in the database.\n\n```diff\ntype User struct {\n    ID     int64  `sql:\"pk: true\"`\n    Login  string\n    Email  string\n+   Label  []string `sql:\"encode: json\"\n}\n```\n\n### Dialects\n\nYou may specify one of the following SQL dialects when generating your code: `postgres`, `mysql` and `sqlite`. The default value is `sqlite`.\n\n```\nsqlgen -file user.go -type User -pkg demo -db postgres\n```\n\n\n### Go Generate\n\nExample use with `go:generate`:\n\n```Go\npackage demo\n\n//go:generate sqlgen -file user.go -type User -pkg demo -o user_sql.go\n\ntype User struct {\n    ID     int64  `sql:\"pk: true, auto: true\"`\n    Login  string `sql:\"unique: user_login\"`\n    Email  string `sql:\"size: 1024\"`\n    Avatar string\n}\n```\n\n### Benchmarks\n\nThis tool demonstrates performance gains, albeit small, over light-weight ORM packages such as `sqlx` and `meddler`. Over time I plan to expand the benchmarks to include additional ORM packages.\n\nTo run the project benchmarks:\n\n```\ngo get ./...\ngo generate ./...\ngo build\ncd bench\ngo test -bench=Bench\n```\n\nExample selecing a single row:\n\n```\nBenchmarkMeddlerRow-4      30000        42773 ns/op\nBenchmarkSqlxRow-4         30000        41554 ns/op\nBenchmarkSqlgenRow-4       50000        39664 ns/op\n\n```\n\nSelecting multiple rows:\n\n```\nBenchmarkMeddlerRows-4      2000      1025218 ns/op\nBenchmarkSqlxRows-4         2000       807213 ns/op\nBenchmarkSqlgenRows-4       2000       700673 ns/op\n```\n\n\n#### Credits\n\nThis tool was inspired by [scaneo](https://github.com/variadico/scaneo).\n","funding_links":[],"categories":["[](https://github.com/golang/go/wiki/CodeTools#code-generation-templating-and-generics)Code generation, Templating and Generics"],"sub_categories":["[](https://github.com/golang/go/wiki/CodeTools#tools)Tools"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrone%2Fsqlgen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrone%2Fsqlgen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrone%2Fsqlgen/lists"}