https://github.com/pardnchiu/go-pg
(Go Package) PostgreSQL client with chained method calls
https://github.com/pardnchiu/go-pg
backend chain-syntax go golang pardnchiu postgresql
Last synced: 24 days ago
JSON representation
(Go Package) PostgreSQL client with chained method calls
- Host: GitHub
- URL: https://github.com/pardnchiu/go-pg
- Owner: pardnchiu
- Created: 2025-10-12T10:10:37.000Z (9 months ago)
- Default Branch: master
- Last Pushed: 2025-10-12T10:13:16.000Z (9 months ago)
- Last Synced: 2026-01-15T04:56:34.917Z (5 months ago)
- Topics: backend, chain-syntax, go, golang, pardnchiu, postgresql
- Language: Go
- Homepage:
- Size: 10.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# PostgreSQL Pool
> Golang PostgreSQL wrapper supporting chain calls, read-write separation, query builder, and complete connection management.
>
> MySQL version [here](https://github.com/pardnchiu/go-mysql)
[](https://pkg.go.dev/github.com/pardnchiu/go-pg)
[](LICENSE)
[](https://github.com/pardnchiu/go-pg/releases)

## Key Features
### Read-Write Separation
Support read-write connection pool configuration, enabling pre-connections to improve efficiency.
### Query Builder
Provide a chainable SQL query builder interface to prevent SQL injection attacks.
### CRUD Operations
Complete support for create, read, update, and delete operations.
### PostgreSQL-Specific Features
- Support for schemas
- ILIKE operator for case-insensitive pattern matching
- ON CONFLICT for upsert operations
- RETURNING clause for insert/update operations
## Dependencies
- [`github.com/lib/pq`](https://github.com/lib/pq)
- [`github.com/joho/godotenv`](https://github.com/joho/godotenv)
## Installation
```bash
go get github.com/pardnchiu/go-pg
```
## Environment Variables
```env
# default 127.0.0.1
PG_READ_HOST=
# default 5432
PG_READ_PORT=
# default postgres
PG_READ_USER=
# default empty
PG_READ_PASSWORD=
# default postgres
PG_READ_DATABASE=
# default disable
PG_READ_SSLMODE=
# default 4
PG_READ_CONNECTION=
# * default is read
PG_WRITE_HOST=
PG_WRITE_PORT=
PG_WRITE_USER=
PG_WRITE_PASSWORD=
PG_WRITE_DATABASE=
PG_WRITE_SSLMODE=
PG_WRITE_CONNECTION=
```
## Configuration
### Method 1: Using Config Struct
```go
config := goPg.Config{
Read: &goPg.DBConfig{
Host: "localhost",
Port: 5432,
User: "postgres",
Password: "password",
Database: "myapp",
SSLMode: "disable",
Connection: 10,
},
Write: &goPg.DBConfig{
Host: "localhost",
Port: 5432,
User: "postgres",
Password: "password",
Database: "myapp",
SSLMode: "disable",
Connection: 5,
},
}
pool, err := goPg.New(config)
```
### Method 2: Using Environment Variables
```go
pool, err := goPg.New()
```
## Query Operations
### Basic Query
```go
rows, err := pool.Read.
Schema("public").
Table("users").
Select("id", "name", "email").
Where("status", "active").
Get()
defer rows.Close()
for rows.Next() {
var id int
var name, email string
rows.Scan(&id, &name, &email)
}
```
### Complex Conditions
```go
rows, err := pool.Read.
Schema("public").
Table("users").
Select("*").
Where("age", ">", 18).
Where("status", "active").
Where("name", "ILIKE", "john"). // Case-insensitive
OrderBy("created_at", "DESC").
Limit(10).
Offset(20).
Get()
```
### JOIN Query
```go
rows, err := pool.Read.
Schema("public").
Table("users").
Select("users.name", "profiles.bio").
LeftJoin("profiles", "users.id", "profiles.user_id").
Where("users.status", "active").
Get()
```
### Query with Total Count
```go
rows, err := pool.Read.
Schema("public").
Table("users").
Select("id", "name").
Where("status", "active").
Total().
Limit(10).
Get()
for rows.Next() {
var total, id int
var name string
rows.Scan(&total, &id, &name)
}
```
## Insert Operations
### Basic Insert
```go
data := map[string]interface{}{
"name": "Jane Doe",
"email": "jane@example.com",
"age": 25,
}
lastID, err := pool.Write.
Schema("public").
Table("users").
Insert(data)
```
## Update Operations
### Basic Update
```go
updateData := map[string]interface{}{
"age": 26,
"status": "updated",
}
result, err := pool.Write.
Schema("public").
Table("users").
Where("id", 1).
Update(updateData)
rowsAffected, _ := result.RowsAffected()
```
### Using PostgreSQL Functions
```go
updateData := map[string]interface{}{
"updated_at": "NOW()",
"last_login": "CURRENT_TIMESTAMP",
}
result, err := pool.Write.
Schema("public").
Table("users").
Where("id", 1).
Update(updateData)
```
### Increase Values
```go
result, err := pool.Write.
Schema("public").
Table("users").
Where("id", 1).
Increase("view_count", 1).
Update()
```
## Upsert Operations
### Basic Upsert
```go
data := map[string]interface{}{
"email": "unique@example.com",
"name": "New User",
"age": 30,
}
// Update all fields on conflict
lastID, err := pool.Write.
Schema("public").
Table("users").
Upsert(data, []string{"email"})
```
### Upsert with Specific Update Fields
```go
data := map[string]interface{}{
"email": "unique@example.com",
"name": "New User",
}
updateData := map[string]interface{}{
"name": "Updated User",
"last_login": "NOW()",
}
lastID, err := pool.Write.
Schema("public").
Table("users").
Upsert(data, []string{"email"}, updateData)
```
## Direct SQL Execution
### Query
```go
rows, err := pool.Read.Query(
"SELECT * FROM users WHERE age > $1 AND status = $2",
18,
"active",
)
```
### Execute
```go
result, err := pool.Write.Exec(
"UPDATE users SET status = $1 WHERE age > $2",
"senior",
35,
)
```
## Supported PostgreSQL Functions
- `NOW()`
- `CURRENT_TIMESTAMP`
- `CURRENT_DATE`
- `CURRENT_TIME`
- `LOCALTIMESTAMP`
- `LOCALTIME`
- `TRANSACTION_TIMESTAMP()`
- `STATEMENT_TIMESTAMP()`
- `CLOCK_TIMESTAMP()`
- `GEN_RANDOM_UUID()`
- `RANDOM()`
- And more...
## Connection Pool Management
```go
defer pool.Close()
```
The package automatically listens for `SIGINT` and `SIGTERM` signals for graceful shutdown.
## Slow Query Logging
Queries taking longer than 20ms are automatically logged.
## Complete Example
```go
package main
import (
"log"
goPg "github.com/pardnchiu/go-pg"
)
func main() {
pool, err := goPg.New()
if err != nil {
log.Fatal(err)
}
defer pool.Close()
// Insert
data := map[string]interface{}{
"name": "John Doe",
"email": "john@example.com",
"age": 30,
}
lastID, _ := pool.Write.Schema("public").Table("users").Insert(data)
// Query
rows, _ := pool.Read.
Schema("public").
Table("users").
Select("id", "name", "email").
Where("age", ">", 18).
OrderBy("created_at", "DESC").
Limit(10).
Get()
defer rows.Close()
for rows.Next() {
var id int
var name, email string
rows.Scan(&id, &name, &email)
log.Printf("User: %s (%s)\n", name, email)
}
// Update
updateData := map[string]interface{}{
"age": 31,
}
pool.Write.Schema("public").Table("users").Where("id", lastID).Update(updateData)
}
```
## License
This project is licensed under the [MIT](LICENSE) license.
## Author

邱敬幃 Pardn Chiu
***
©️ 2025 [邱敬幃 Pardn Chiu](https://pardn.io)