Support .pgpass files for migra

This eases the whole connection URI setup for developers who make use of the
.pgpass file.

Signed-off-by: Wesley Schwengle <wesley@opndev.io>
This commit is contained in:
Wesley Schwengle 2022-05-28 12:58:04 -04:00
parent da6671acae
commit c5c5c58b22
3 changed files with 57 additions and 1 deletions

View File

@ -26,6 +26,12 @@ The general form is as follows:
:::bash
connectiontype://username:password@databasehostname/databasename?extraparam1=a&extraparam2=b
If you have a .pgpass file in your $HOME dir, you can make use of that as well
as you don't need to enter the password in the connection string:
:::bash
postgresql://username@hostname/databasename
These can be left out if not necessary. For instance, if connecting locally, using your default system username and passwordless "trust" login, only a connection type and database name is required:
:::bash

View File

@ -1,8 +1,13 @@
from __future__ import print_function, unicode_literals
import argparse
import pgpasslib
import sys
import getpass
from contextlib import contextmanager
from sqlalchemy.engine.url import make_url
from sqlbag import S
from .migra import Migration
from .statements import UnsafeMigrationException
@ -75,6 +80,46 @@ def parse_args(args):
return parser.parse_args(args)
def get_password_from_pgpass(host, port, database, username):
if not host:
host = "localhost"
if not port:
port = 5432
if not username:
username = getpass.getuser()
if not database:
database = username
try:
return pgpasslib.getpass(
host,
port,
database,
username,
)
except pgpasslib.FileNotFound:
return None
return None
def get_password_from_uri(uri):
uri = make_url(uri)
if not uri.password:
password = get_password_from_pgpass(
uri.host, uri.port, uri.database, uri.username
)
if password:
uri.set(password=password)
return uri
def run(args, out=None, err=None):
schema = args.schema
exclude_schema = args.exclude_schema
@ -82,7 +127,11 @@ def run(args, out=None, err=None):
out = sys.stdout # pragma: no cover
if not err:
err = sys.stderr # pragma: no cover
with arg_context(args.dburl_from) as ac0, arg_context(args.dburl_target) as ac1:
db_from = get_password_from_uri(args.dburl_from)
db_to = get_password_from_uri(args.dburl_target)
with arg_context(db_from) as ac0, arg_context(db_to) as ac1:
m = Migration(
ac0,
ac1,

View File

@ -16,6 +16,7 @@ six = "*"
# schemainspect = {path="../schemainspect", develop=true}
schemainspect = ">=3.1.1663480743"
psycopg2-binary = { version="*", optional = true }
pgpasslib = "*"
[tool.poetry.dev-dependencies]
sqlbag = "*"