I'm trying to create database users in my Postgres database from Golang, and I can't seem to get queries to run.
I'm able to establish a connection, but I cannot run create user X with password Y and I've tried multiple ways of doing this, and searching the internet has not yielded any results. I'm building a database migrator wrapper utility and I need to manage these users manually as their credentials are being sourced from secrets. I'm using pq as my driver.
I've tried the following:
// fails with syntax error re $
res, err := db.ExecContext(ctx, "create user $1 with password $2", username, password)
// fails with syntax error re ?
res, err := db.ExecContext(ctx, "create user ? with password ?", username, password)
The only examples I've found on the internet use fmt.Sprintf but obviously that's a bad idea due to SQL injection attacks.
Is there a specific function I need to be using when operating on Postgres users/roles/other items? I need to issue grant statements after this so I'm not sure if it will follow the same pattern.
I was unaware that pg is headed toward deprecation, so as recommended in the comments below, I have switched to github.com/jackc/pgx/v5. However, I'm still having issues and I can't see in the documentation how to accomplish what I'm looking to do.
I'm now operating with a pgx.Conn directly instead of through the sql facade so I can take full advantage of all of the features provided by pgx.
I'm running a local Docker container for postgres:15.10 and I'm trying to create a user janedoe with a password of password.
Attempt 1: Use pgx.Identifier to Sanitize Both Username and Password
queryTemplate := fmt.Sprintf(
"create user %s with password %s",
pgx.Identifier{username}.Sanitize(),
pgx.Identifier{password}.Sanitize(),
)
result, err := pgx.Exec(ctx, queryTemplate)
This returns ERROR: syntax error at or near ""password"" (SQLSTATE 42601). I've tried including a final semicolon at the end of the statement and that doesn't fix things.
It seems that Postgres wants this string to not be double-quoted but single-quoted, and I don't see a way in pgx to specify the kind of escaping that I want.
create user $1 with password $2the$1and$2are literals not parameters that can be passed in withusername, password. I don't see anything inpqthat allows you to safely build dynamic queries, so I would take @FrankHeikens advice and move offpq. 2) An option is to create your own Postgres function that accepts arguments and then does theCREATE USERsafely using format.pgxinstead ofpg, so I'll update my question, but I'm still having trouble building a query.CREATE USERis an alias forCREATE ROLE. Thepasswordis a string not an identifier which is why you are getting the error. Thepgxdocumentation is sparse and I don't use Golang so I don't know whetherpgxhas something likepgx.Literal .Sanitize()to deal with strings. Or maybe try passing the password as a parameter.