Queryx: An Open-Source Golang ORM with Automatic Schema Management
Tags: go, orm, postgres
Published: 2023-07-06 05:23:44

---
title: Queryx: An Open-Source Golang ORM with Automatic Schema Management
published: true
description: 
tags: golang,orm,postgresql
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-01-22 12:23 +0000
---

Github link: https://github.com/swiftcarrot/queryx

Installation:

```sh
curl -sf https://raw.githubusercontent.com/swiftcarrot/queryx/main/install.sh  | sh
```

## schema.hcl

Queryx uses `schema.hcl` to describe the database. The following example defines database environments and models:

```hcl
database "db" {
  adapter = "postgresql"

  config "development" {
    url = "postgres://postgres:postgres@localhost:5432/blog_development?sslmode=disable"
  }

  config "production" {
    url = env("DATABASE_URL")
  }

  generator "client-golang" {}

  model "Post" {
    column "title" {
      type = string
    }
    column "content" {
      type = text
    }
  }
}
```

Run the `queryx db:create` command to create a PostgreSQL database, and then run `queryx db:migrate` to automatically create the database migration files and database structure. Queryx’s database schema management is built upon [Atlas](https://atlasgo.io/). 

## CRUD

Running `queryx g` generates corresponding ORM code in the `db` directory. The generated code generates Go types based on the database schema and has no other third-party dependencies except for the `lib/pq` driver. We hope that the automatically generated code is concise and readable.

Below are some sample code for CRUD operations:

```go
// Create
newPost := c.ChangePost().SetTitle("post title")
post, err := c.QueryPost().Create(newPost)

// Read
post, err := c.QueryPost().Find(1)
posts, err := c.QueryPost().Where(c.PostTitle.EQ("post title")).All()

// Update
updatePost := c.ChangePost().SetTitle("new post title")
err := post.Update(updatePost)
updated, err := c.QueryPost().Where(c.PostTitle.EQ("post title")).UpdateAll(updatePost)

// Delete
err := post.Delete()
deleted, err := c.QueryPost().Where(c.PostTitle.EQ("post title")).DeleteAll()
```

## Relationships

Relationships between models, including `belongs_to`, `has_one`, and `has_many`, can also be declared in `schema.hcl`. For example:

```hcl
model "User" {
  belongs_to "group" {}

  column "name" {
    type = string
  }
}

model "Group" {
  has_many "users" {}

  column "name" {
    type = string
  }
}
```

After declaring the relationship, you can use the generated `preload` method to avoid n+1 queries. For example:

```go
users, err := c.QueryUser().PreloadGroup().All()
// users[0].Groups

groups, err := c.QueryGroup().PreloadUsers().All()
// groups[0].User
```

If you are familiar with Rails, you will find that Queryx references many design concepts from ActiveRecord. We hope to replicate the development experience of ActiveRecord. For more queryx usages, please refer to the README documentation, and feel free to discuss in the issue, discussion, and reply. Queryx is currently in beta (v0), and many features are still under development such as MySQL support. We hope to continue to improve the development experience in future versions.