Google Cloud integration for pgx v5, supporting Cloud SQL connections via the Cloud SQL Connector, plus query caching backends using Firestore, Datastore, and Cloud Storage.
- Cloud SQL Connector — connect to Cloud SQL instances via
pgx.ConnConfig.BeforeConnectusing the Cloud SQL Proxy dialer - FirestoreQueryCacher — query result caching backed by Google Firestore (implements pgxcache)
- DatastoreQueryCacher — query result caching backed by Google Datastore (implements pgxcache)
- StorageQueryCacher — query result caching backed by Google Cloud Storage (implements pgxcache)
go get github.com/pgx-contrib/pgxgcpThe Connector uses the Cloud SQL Proxy dialer to connect to Cloud SQL instances. It hooks into pgx.ConnConfig.BeforeConnect and replaces the dial function when GOOGLE_APPLICATION_CREDENTIALS is set.
config, err := pgxpool.ParseConfig(os.Getenv("PGX_DATABASE_URL"))
if err != nil {
panic(err)
}
ctx := context.TODO()
// Create a new pgxgcp.Connector
connector, err := pgxgcp.Connect(ctx)
if err != nil {
panic(err)
}
// Set BeforeConnect hook to connector.BeforeConnect
config.BeforeConnect = connector.BeforeConnect
// Create a new pgxpool with the config
conn, err := pgxpool.NewWithConfig(ctx, config)
if err != nil {
panic(err)
}
rows, err := conn.Query(ctx, "SELECT * from organization")
if err != nil {
panic(err)
}
defer rows.Close()
type Organization struct {
Name string `db:"name"`
}
for rows.Next() {
organization, err := pgx.RowToStructByName[Organization](rows)
if err != nil {
panic(err)
}
fmt.Println(organization.Name)
}Cache query results in Google Firestore using pgxcache:
// Create a new client
client, err := firestore.NewClient(context.TODO(), os.Getenv("GOOGLE_PROJECT_ID"))
if err != nil {
panic(err)
}
// Create a new cacher
cacher := &pgxgcp.FirestoreQueryCacher{
Client: client,
Collection: "queries",
}
// create a new querier
querier := &pgxcache.Querier{
Options: &pgxcache.QueryOptions{
MaxLifetime: 30 * time.Second,
MaxRows: 1,
},
Cacher: cacher,
Querier: conn,
}
rows, err := querier.Query(context.TODO(), "SELECT * from customer")Cache query results in Google Datastore using pgxcache:
// Create a new client
client, err := datastore.NewClient(context.TODO(), os.Getenv("GOOGLE_PROJECT_ID"))
if err != nil {
panic(err)
}
// Create a new cacher
cacher := &pgxgcp.DatastoreQueryCacher{
Client: client,
Kind: "queries",
}
// create a new querier
querier := &pgxcache.Querier{
Options: &pgxcache.QueryOptions{
MaxLifetime: 30 * time.Second,
MaxRows: 1,
},
Cacher: cacher,
Querier: conn,
}
rows, err := querier.Query(context.TODO(), "SELECT * from customer")Cache query results in Google Cloud Storage using pgxcache:
// Create a new client
client, err := storage.NewClient(context.TODO())
if err != nil {
panic(err)
}
// Create a new cacher
cacher := &pgxgcp.StorageQueryCacher{
Client: client,
Bucket: "queries",
}
// create a new querier
querier := &pgxcache.Querier{
Options: &pgxcache.QueryOptions{
MaxLifetime: 30 * time.Second,
MaxRows: 1,
},
Cacher: cacher,
Querier: conn,
}
rows, err := querier.Query(context.TODO(), "SELECT * from customer")Open in VS Code with the Dev Containers extension. The environment provides Go, PostgreSQL 18, and Nix automatically.
PGX_DATABASE_URL=postgres://vscode@postgres:5432/pgxgcp?sslmode=disable
nix develop # enter shell with Go
go tool ginkgo run -r# Unit tests only (no database required)
go tool ginkgo run -r
# With integration tests
export PGX_DATABASE_URL="postgres://localhost/pgxgcp?sslmode=disable"
go tool ginkgo run -rIntegration tests require real GCP infrastructure and are guarded by environment variables — they are skipped automatically when the variables are not set:
| Variable | Used by |
|---|---|
PGXGCP_CLOUD_SQL_INSTANCE |
Connector (e.g. project:region:instance) |
GOOGLE_PROJECT_ID |
FirestoreQueryCacher, DatastoreQueryCacher |
PGXGCP_FIRESTORE_COLLECTION |
FirestoreQueryCacher |
PGXGCP_DATASTORE_KIND |
DatastoreQueryCacher |
PGXGCP_STORAGE_BUCKET |
StorageQueryCacher |