Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pgx driver package #517

Merged
merged 14 commits into from
Mar 14, 2021
Merged

Conversation

dzbee
Copy link
Contributor

@dzbee dzbee commented Mar 3, 2021

Closes #512

Changes:

  • Replace lib/pq dependency with pgx/stdlib in the postgres driver
  • Replace use of pq.QuoteIdentifier with private quoteIdentifier function in package
  • Slight change around parsing of cursor position from PgError (which is an int32 in pgx.PgError rather than string as in pq.PgError)

This PR would slightly change error reporting to include the SQL error code in the error message. If this is considered a backwards compatibility breaking change, I could add some parsing to omit the code so that this would only be a minor update rather than a major update, but I can't imagine that including additional information in the error message merits a major bump in the first place.

@coveralls
Copy link

coveralls commented Mar 3, 2021

Pull Request Test Coverage Report for Build 183

  • 188 of 290 (64.83%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.4%) to 56.547%

Changes Missing Coverage Covered Lines Changed/Added Lines %
database/pgx/pgx.go 188 290 64.83%
Totals Coverage Status
Change from base Build 143: 0.4%
Covered Lines: 3308
Relevant Lines: 5850

💛 - Coveralls

Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Good to know that the smoke tests pass!
The different error messages may break existing postgres users. e.g. if they were handling said errors
Also, I believe WithInstance() may behave differently using pgx/stdlib instead of lib/pq, forcing users to migrate to pgx.

I'll hold off on merging this until there is more demand for it.

if _, err = p.conn.ExecContext(context.Background(), query); err != nil {
return &database.Error{OrigErr: err, Query: []byte(query)}
}

return nil
}

func quoteIdentifier(s string) string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use this implementation and reference it: https://github.com/lib/pq/blob/v1.9.0/conn.go#L1611

@dzbee
Copy link
Contributor Author

dzbee commented Mar 4, 2021

@dhui With regards to concerns about creating conflicts for lib/pq users in the near-term, I wonder if you would consider relaxing this intention while the future of lib/pq vs pgx (or another replacement) remains unresolved:

...there should really just be one driver for a database...

To ease the transition from lib/pq to pgx I could split these changes out into a pgx.go and register the driver with that name instead of "postgres". Indeed lib/pq in some sense "owns" the "postgres" driver identifier whereas pgx/stdlib uses "pgx" to avoid conflicts on initialization in cases where both modules are imported. Given that the spirit of this rule is

We want to prevent a future where several drivers doing the exact same thing, just implemented a bit differently, co-exist somewhere on GitHub.

I don't think this change would contribute to such a future because lib/pq will eventually be disfavored in the community since it is not being actively developed.

Let me know what you think about this alternative.

@dhui
Copy link
Member

dhui commented Mar 5, 2021

Registering pgx as a separate migrate db driver is a great idea! e.g. following pgx/stdlib's lead
That way users can pick which postgres db driver to use. I'd hold off on recommending using pgx until the more of the community has moved over.

Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests are failing

@@ -0,0 +1,38 @@
# postgres
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to pgx

@@ -0,0 +1,38 @@
# postgres

`postgres://user:password@host:port/dbname?query` (`postgresql://` works, too)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the DSN

database/pgx/README.md Show resolved Hide resolved
database/pgx/pgx.go Show resolved Hide resolved
go.mod Outdated
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
github.com/jackc/pgconn v1.3.2
github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451
github.com/jackc/pgx v3.6.2+incompatible
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like v4.10.1 is the latest release. Any reason why we don't use that?

Copy link
Contributor Author

@dzbee dzbee Mar 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was simply a mistake resulting from the fact that pgx didn't support Go modules until v4. Therefore I was pulling the latest release prior to the introduction of modules into the project. The major version includes some breaking changes for the code I'd written before so I've included some updates with a version bump in def44ba.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most significantly, in v3 the connection string parsing didn't include any checks on the content scheme name (see https://github.com/jackc/pgx/blob/a413de981978e4100d5736af7aaa2b392511612f/conn.go#L1246 and https://github.com/jackc/pgx/blob/a413de981978e4100d5736af7aaa2b392511612f/conn.go#L979) whereas now the postgres or postresql schemes are explicitly required in the connection string (see https://github.com/jackc/pgconn/blob/5daa019e4eb52df3409ebf17c83116b7c0e827e5/config.go#L199). Therefore I've introduced a string replacement so that after the pgx scheme is used to identify the appropriate driver in migrate, it's replaced with the appropriate postgres scheme for actually opening the connection.

Prior to v4, pgx did not support go modules. Version locking the import is the safest way to ensure we get the (as of now) latest version of the module. Additionally v4 implements some breaking changes to connection and error handling, which are also addressed in this commit.
Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the breaking changes in connection and error handling. It just looks like the connection errors were moved to another package.

// Driver is registered as pgx, but connection string must use postgres schema
// when making actual connection
// i.e. pgx://user:password@host:port/db => postgres://user:password@host:port/db
url = strings.Replace(url, "pgx://", "postgres://", 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid manipulating URLs via string operations. Instead, set purl.Scheme.
I like the documentation in the comments though. Let's keep that!

@dzbee
Copy link
Contributor Author

dzbee commented Mar 11, 2021

Connection errors were moved and connection string parsing was changed (#517 (comment)), but that's all. I just meant to explain why there were additional code changes accompanying the upgrade from v3 -> v4.

@dzbee dzbee changed the title Replace lib/pq dependency with pgx in postgres driver Add pgx driver package Mar 11, 2021
dhui
dhui previously approved these changes Mar 12, 2021
Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR and addressing all of the feedback!
If you want pgx bundled in the CLI releases, you'll need to update DATABASE in the Makefile.

@dzbee
Copy link
Contributor Author

dzbee commented Mar 12, 2021

Thanks for the tip, I definitely missed that. And thanks for working with me to get this added! It's a big help.

README.md Outdated
@@ -1,3 +1,23 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the generated TOC. If we add this, we're likely to use a different generator.

@dhui dhui merged commit 2f0c075 into golang-migrate:master Mar 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace lib/pq with pgx/stdlib as postgres driver
3 participants