{"id":27042263,"url":"https://github.com/ngorm/ngorm","last_synced_at":"2026-03-12T12:08:56.932Z","repository":{"id":46960686,"uuid":"80344413","full_name":"ngorm/ngorm","owner":"ngorm","description":"Neo GORM: The modern fork of gorm The fantastic ORM( Object Relational Mapper ) for Go","archived":false,"fork":false,"pushed_at":"2021-09-20T13:16:48.000Z","size":2633,"stargazers_count":37,"open_issues_count":2,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-05T04:24:57.383Z","etag":null,"topics":["database","golang","mysql","ngorm","orm","postgresql","ql","sql-server","sqlite"],"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/ngorm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"License","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-29T12:18:49.000Z","updated_at":"2021-11-09T23:16:10.000Z","dependencies_parsed_at":"2022-09-16T16:20:31.407Z","dependency_job_id":null,"html_url":"https://github.com/ngorm/ngorm","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/ngorm/ngorm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngorm%2Fngorm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngorm%2Fngorm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngorm%2Fngorm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngorm%2Fngorm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngorm","download_url":"https://codeload.github.com/ngorm/ngorm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngorm%2Fngorm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262702324,"owners_count":23350641,"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":["database","golang","mysql","ngorm","orm","postgresql","ql","sql-server","sqlite"],"created_at":"2025-04-05T04:22:16.935Z","updated_at":"2026-03-12T12:08:56.861Z","avatar_url":"https://github.com/ngorm.png","language":"Go","readme":"# NGORM\n\n The fork of gorm,The fantastic ORM( Object Relational Mapping) library for Golang, that focus on\n\n* Performance\n* Maintainability\n* Modularity\n* Battle testing\n* Extensibility\n* Safety\n* Developer friendly for real\n\n[![GoDoc](https://godoc.org/github.com/ngorm/ngorm?status.svg)](https://godoc.org/github.com/ngorm/ngorm)[![Coverage Status](https://coveralls.io/repos/github/ngorm/ngorm/badge.svg?branch=master)](https://coveralls.io/github/ngorm/ngorm?branch=master)[![Build Status](https://travis-ci.org/ngorm/ngorm.svg?branch=master)](https://travis-ci.org/ngorm/ngorm)\n\n__IMPORTANT__: This is not meant to replace gorm. For advanced users you might find this library lacking, I advice you use gorm instead.\n\n## Overview\n\n* Full-Featured ORM (almost)\n* Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism)\n* Preloading (eager loading)\n* Transactions\n* Composite Primary Key\n* SQL Builder\n* Auto Migrations\n\nDocumentation https://godoc.org/github.com/ngorm/ngorm\n\nDatabase support\n\n- [x] [ql](https://godoc.org/github.com/cznic/ql)\n- [x] postgresql\n- [ ] [WIP} mysql\n- [ ] mssql\n- [ ] sqlite\n\n\n# Table of contents\n- Introduction\n  - [Synopsis](#synopsis)\n  - [Installation](#installation)\n  - [Connecting to a database](#connecting-to-a-database)\n  - [Migration](#migrations)\n\n- API\n  - [AddForeignKey](#addforeignkey)\n  - [AddIndex](#addforeignkey)\n  - [AddUniqueIndex](#adduniqueindex)\n  - [Assign](#assign)\n  - [Association](#association)\n  - [Attrs](#attrs)\n  - [Automigrate](#automigrate)\n  - [Count](#Count)\n  - [CreateTable](#createtable)\n  - [Delete](#delete)\n  - [Dialect](#dialect)\n  - [DropColumn](#dropcolumn)\n  - [DropTable](#droptable)\n  - [DropTableIfExests](#droptableifexests)\n  - [Find](#find)\n  - [First](#first)\n  - [FirstOrCreate](#firstorcreate)\n  - [FirstOrInit](#firstorinit)\n  - [Group](#group)\n  - [HasTable](#hastable)\n  - [Having](#having)\n  - [Set](#set)\n  - [Joins](#joins)\n  - [Last](#last)\n  - [Limit](#limit)\n  - [Model](#model)\n  - [ModifyColumn](#modifycolumn)\n  - [Not](#not)\n  - [Offset](#offset)\n  - [Omit](#Omit)\n  - [Or](#or)\n  - [Order](#order)\n  - [Pluck](#pluck)\n  - [Preload](#preload)\n  - [Related](#related)\n  - [RemoveIndex](#removeindex)\n  - [Save](#save)\n  - [Select](#select)\n  - [SingulatTable](#singulattable)\n  - [Table](#table)\n  - [Update](#update)\n  - [UpdateColumn](#updatecolumn)\n  - [UpdateColumns](#updatecolumns)\n  - [Updates](#updates)\n  - [Where](#where)\n\n\n# Synopsis\n\nWelcome, I have been looking for ways to work with ql database. Since I was\nfamiliar with gorm I tried to add ql dialect. A task that proved too hard due to\nlimitation of gorm.\n\nI had to rework internals on gorm to reach my end goal. Along the way I had a\nvision on how gorm should have looked like if I were to build it today.\n\nThe new codebase is in a good shape. One of the benifits is now, you can inspect\nthe expected queries without excuting anything (for some methods), eg\n`db.FIndSQL` will return the query for finding an item/items without hitting the\ndatabase.\n\nWith the new code base, it is easy to improve as the building blocks are all\nvisible and well documented. There is also proper error handling. The error\nhandling is consistent with other Go libraries, no exceptions are raised but\nerrors are returned so the application developers can handle them.\n\n## Installation\n\n\tgo get -u github.com/ngorm/ngorm\n\nYou also need to install the dialects(database drivers)\n\n\tgo get -u github.com/ngorm/ql #ql dialect\n\tgo get -u github.com/ngorm/postgres #postgresql dialect\n\n\n## Connecting to a database\n\nNGORM uses a similar API as the one used by `database/sql` package to connect\nto a database.\n\n\u003e connections to the databases requires importing of the respective driver\n\n```go package main\n\nimport (\n\t\"log\"\n\n\t// You must import the driver for the database you wish to connect to. In\n\t// this example I am using the ql and postgresql driver, this should work similar for the\n\t// other supported databases.\n\n    // driver for postgresql database\n\t_ \"github.com/ngorm/postgres\"\n    // driver for ql database\n\t_ \"github.com/ngorm/ql\"\n\t\"github.com/ngorm/ngorm\"\n)\n\nfunc main() {\n\n\t// The first argument is the dialect or the name of the database driver that\n\t// you wish to to connect to, the second argument is connection information\n\t// please check the appropriate driver for more information on the arguments\n\t// that are passed to database/sql Open.\n\tdb, err := ngorm.Open(\"ql-mem\", \"est.db\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Do something with db\n}\n```\n\nThe returned `ngorm.DB` instance is safe. It is a good idea to have only one\ninstance of this object throughout your application life cycle. Make it a global\nor pass it in context.\n\n## Migrations\nngorm support automatic migrations of models. ngorm reuses the gorm logic for\nloading models so all the valid gorm models are also valid ngorm model.\n\n```go\n\ttype Profile struct {\n\t\tmodel.Model\n\t\tName string\n\t}\n\ttype User struct {\n\t\tmodel.Model\n\t\tProfile   Profile\n\t\tProfileID int64\n\t}\n\n\tdb, err := Open(\"ql-mem\", \"test.db\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer func() { _ = db.Close() }()\n\n\t// you can inspect expected generated query\n\ts, err := db.AutomigrateSQL(\u0026User{}, \u0026Profile{})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(s.Q)\n\n\t// Or you can execute migrations like so\n\t_, err = db.Begin().Automigrate(\u0026User{}, \u0026Profile{})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\t//Output:\n\t// BEGIN TRANSACTION;\n\t// \tCREATE TABLE users (id int64,created_at time,updated_at time,deleted_at time,profile_id int64 ) ;\n\t// \tCREATE INDEX idx_users_deleted_at ON users(deleted_at);\n\t// \tCREATE TABLE profiles (id int64,created_at time,updated_at time,deleted_at time,name string ) ;\n\t// \tCREATE INDEX idx_profiles_deleted_at ON profiles(deleted_at);\n\t// COMMIT;\n  ```\n\n\n# API\n\nngorm api borrows heavily from gorm. \n\n##  AddForeignKey\n\n##  AddIndex\n\n##  AddUniqueIndex\n\n##  Assign\n\n##  Association\n\n##  Attrs\n\n##  Automigrate\n\n\n##  Count\nReturns the number of matched rows for a given query.\n\nYou can count the number of all users like this.\n```go\nvar count int64\ndb.Model(\u0026user).Count(\u0026count)\n```\n\nWhich will execute\n\n```sql\nSELECT count(*) FROM users  \n```\nYou can build a normal query by chaining methods and call `Count` at the end,\nthat way the query will be executed and the matched rows will be counted.\n\n##  CreateTable\n\nCreates a new database table if the table doesn't exist yet. This is useful for\ndoing database migrations\n\ne.g\n\nYou have the following model\n\n```go\n\ttype User struct {\n\t\tID       int64\n\t\tName     string\n\t\tPassword string\n\t\tEmail    string\n\t}\n```\n\n```go\ndb.CreateTable(\u0026User{})\n```\n\nWill execute the following query\n\n```sql\nBEGIN TRANSACTION; \n\tCREATE TABLE users (id int64,name string,password string,email string ) ;\nCOMMIT;\n```\n\nChecking if the table exists already is handled separately by the dialects.\n\n##  Delete\nExecutes `DELETE` query, which is used to delete rows from a database table.\n\n```go\ndb.Begin().Delete(\u0026Users{ID: 10})\n```\n\nWill execute \n```sql\nBEGIN TRANSACTION;\n\tDELETE FROM users  WHERE id = $1;\nCOMMIT;\n```\n\nWhere `$1=10`\n\n##  Dialect\nGives you the instance of dialect which is registered in the `DB`. \n\n##  DropColumn\n\nRemoves columns from database tables by issuing `ALTER TABLE`.\n\nFor instance,\n\n```go\ndb.Model(\u0026USer{}).DropColumn(\"password\")\n//ALTER TABLE users DROP COLUMN password\n```\n\n##  DropTable\n\nExecutes `DROP Table` query. Use this to get rid of database tables. This is the\nopposite of `CreateTable` whatever `CreateTable` does to the database this\nundoes it.\n\n##  DropTableIfExests\n\nThis will check if the table exist in the database before dropping it by calling `DropTable`.\n\n##  Find\n\nFind is used for looking up things in the database. You can look for one item or\na list of items. This works well will the other query building API calls.\nSomething to no note is this is the last call after chaining other API calls.\nSo, you can have something similar to `db.Where(...).Find()` etc.\n\nThis is an example of looking up for all users.\n\n```go\n\ttype User struct {\n\t\tID   int64\n\t\tName string\n\t}\n\n\tdb, err := Open(\"ql-mem\", \"test.db\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer func() { _ = db.Close() }()\n\t_, err = db.Automigrate(\u0026User{})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tv := []string{\"gernest\", \"kemi\", \"helen\"}\n\tfor _, n := range v {\n\t\terr = db.Begin().Save(\u0026User{Name: n})\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t}\n\n\tusers := []User{}\n\terr = db.Begin().Find(\u0026users)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfor _, u := range users {\n\t\tfmt.Println(u.Name)\n\t}\n\n\t//Output:\n\t// helen\n\t// kemi\n\t// gernest\n```\n\n\n##  First\n\nFirst  fetches the first record and order by primary key.\n\nFor instance,\n\n```go\ndb.Begin().First(\u0026user)\n```\n\nWill execute,\n```sql\nSELECT * FROM users   ORDER BY id ASC LIMIT 1\n```\n\nFirst user by primary key\n\n```go\ndb.Begin().First(\u0026user,10)\n```\n\nwill execute\n\n```sql\nSELECT * FROM users  WHERE (id = $1) ORDER BY id ASC LIMIT 1\n```\nWhereby `$1=10`\n\nYou can chain other methods as well to build complex queries.\n\n##  FirstOrCreate\n\nThis will first try to find the first record that matches, when there is no\nmatch a new record is created.\n\n##  FirstOrInit\n\n##  Group\n\n##  HasTable\n\nReturns true if there is a table for the given value, the value can\neither be a string representing a table name or a ngorm model.\n\n##  Having\n\nBuilds `HAVING` SQL\n\n##  Set\n\nStore temporary values that will be available across  db chains. The values are\nvisible at scope leve.\n\n##  Joins\n\nAdd `JOIN` SQL\n\n##  Last\n\nReturns the Last row to match the query.\n\nYou can gen the last user by\n```go\nvar user User\ndb.Last(\u0026user)\n```\n\nWhich will execute the following query\n\n```sql\nSELECT * FROM users   ORDER BY id DESC LIMIT 1\n```\n\n##  Limit\n\nAdd `LIMIT` SQL clause\n\n##  Model\n\nSets the value as the scope value for the db instance. value must be a valid\nngorm model.\n\nThis paves way for chainable query building, since most methods operate on the\nscoped model value.\n\nBy calling `db.Model(\u0026user)` we are stating that out primary model we want to perate on is `\u0026user`, now from there we can chain further methods to get what we want. like `db.Model(*user).Limit(2).Offset(4).Find(\u0026users)`\n\n##  ModifyColumn\n\n##  Not\n\n##  Offset\n\nAdd `OFFSET` SQL clause\n\n##  Omit\n\nUse this to setup fields from the model to be skipped.\n\n\n##  Or\n\nAdd `OR` SQL clause\n\n##  Order\n\nAdd `ORDER BY` SQL clause\n\n##  Pluck\n\n\n##  Preload\n\n##  Related\n\n##  RemoveIndex\n\n##  Save\n\n##  Select\n\nUse this to compose `SELECT` queries. The first argument is the Query and you\ncan  pass any positional arguments after it.\n\neg\n```go\ndb.Select(\"count(*)\")\n```\n\nThis will build `SELECT count(*)`\n\n\n##  SingulatTable\n\nSingularTable enables or disables singular tables name. By default this is\ndisabled, meaning table names are in plural.\n```\n\tModel\t| Plural table name\n\t----------------------------\n\tSession\t| sessions\n\tUser\t| users\n\n\tModel\t| Singular table name\n\t----------------------------\n\tSession\t| session\n\tUser\t| user\n```\n\nTo enable singular tables do,\n```go\ndb.SingularTable(true)\n```\n\nTo disable singular tables do,\n```go\ndb.SingularTable(false)\n```\n##  Table\nThis specify manually the database table you want to run operations on. Most\noperations are built automatically from models.\n\nFor instance, to find all users you can do `db.Find(\u0026users)` which might\ngenerate `SELECT * FROM users;`. \n\nYou can  select from `scary_users` instead by,\n\n```go\ndb.Begin().Table(\"scary_users\").Find(\u0026users)\n// SELECT * FROM scary_users\n```\n\n##  Update\n\n##  UpdateColumn\n\n##  UpdateColumns\n\n##  Updates\n\n##  Where\n\nThis generates `WHERE` SQL clause.\n\nUsing Where with plain SQL\n\n```go\ndb.Where(\"name\",\"gernest\")\n\n// WHERE (name=$1)\n//$1=\"gernest\"\n```\n\nUsing Where `IN`\n\n```go\ndb.Where(e, \"name in (?)\", []string{\"gernest\", \"gernest 2\"})\n// WHERE (name in ($1,$2))\n// $1=\"gernest\", $2=\"gernest 2\"\n```\n\nUsing Where with `LIKE`\n\n```go\ndb.Where(e, \"name LIKE ?\", \"%jin%\")\n// WHERE (name LIKE $1)\n//$1=\"%jin%\"\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngorm%2Fngorm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngorm%2Fngorm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngorm%2Fngorm/lists"}