Writing a Go application with PostgreSQL using pgx
Henrique Vicente
Trajectory to PostgreSQL
Migration from a document-oriented database to�PostgreSQL (RDS) + OpenSearch (Amazon's fork of Elasticsearch)
Problems with previous database
Why PostgreSQL
PostgreSQL advantages
PostgreSQL drawbacks
Environment variables for configuring PostgreSQL�https://www.postgresql.org/docs/current/libpq-envars.html
Environment variables might be problematic due to security concerns, so be careful.
Also:
Tip: direnv makes it very convenient to use it on a development environment.
database/sql vs. pgx interface
Talking to SQL databases in Go, you almost always want to use a database through database/sql.
It provides a nice common interface, and makes supporting different databases easier.
PostgreSQL drivers for database/sql:
database/sql vs. pgx interface
Among better performance, by using pgx interface you've:
database/sql is limited to int64, float64, bool, []byte, string, time.Time, or nil
Concurrency: pgxpool
Default:
conf.MaxConns = runtime.NumCPU()
Database migrations: 001_initial_schema.sql, 002_…
tern: standalone migration tool�https://asciinema.org/a/450576
Database layer
It might be useful to define an interface, even if bothersome.
What about mocks?
Testing strategy
Get superior returns from your tests:
Inspiration: Software Engineering at Google: Lessons Learned from Programming Over Time�https://amzn.to/3uqZWP7
Real implementation | Test doubles (mocks, fakes…) |
SELECT returning data or not found. | Database connection issue. |
INSERT, UPDATE, etc. | Simulation of unexpected DB error. |
Constraints checks. | Expensive operation (ask why first) |
Just like Theranos' blood tests…
Testing interfaces for the sake of it is overrated.
Some tools
GoMock
Comparing values with go-cmp
scany
pgtools
github.com/hatch-studio/pgtools contains:
Tests with sqltest
DON'T
sqltest + tern = easy tests https://asciinema.org/a/450576
Then you discover running its integration tests is hard.
$ go test ./…
From zero to running integration tests in few seconds. Try it:
Continuous Integration
Run your DB on any CI/CD system.
For example, with a pull request workflow on GitHub Actions, stateless.
Proof it works https://asciinema.org/a/450580
Takeaways
Thanks. Questions?
Henrique Vicente, HATCH Studio