Source code for testsuite.databases.pgsql.connection

# pylint: disable=no-member
import typing
import urllib.parse

import psycopg2.extensions


class _NotSet:
    pass


[docs]class PgConnectionInfo(typing.NamedTuple): """ PostgreSQL connection parameters """ host: typing.Optional[str] = None port: typing.Optional[int] = None user: typing.Optional[str] = None password: typing.Optional[str] = None options: typing.Optional[str] = None sslmode: typing.Optional[str] = None dbname: typing.Optional[str] = None
[docs] def get_dsn(self) -> str: """PostgreSQL connection string in DSN format""" return psycopg2.extensions.make_dsn( host=self.host, port=self.port, user=self.user, password=self.password, options=self.options, sslmode=self.sslmode, dbname=self.dbname, )
[docs] def get_uri(self) -> str: """PostgreSQL connection string in URI format""" return get_connection_uri(**self._asdict())
[docs] def replace(self, **kwargs) -> 'PgConnectionInfo': """Return a new :py:class:`PgConnectionInfo` value replacing specified fields with new values """ return self._replace(**kwargs)
def parse_connection_string(connstr: str) -> PgConnectionInfo: """Parse PostgreSQL connection string. :param connstr: connection string in DSN or URI format as specified in https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING """ kwargs = psycopg2.extensions.parse_dsn(connstr) for key, value in kwargs.items(): if key not in PgConnectionInfo._fields: continue if key == 'port': kwargs[key] = int(value) else: kwargs[key] = value return PgConnectionInfo(**kwargs) def get_connection_uri(**kwargs): kwargs = {key: value for key, value in kwargs.items() if value is not None} dbname = kwargs.pop('dbname', '') if kwargs: items = ( (key, urllib.parse.quote(str(value))) for key, value in kwargs.items() ) query = '?' + '&'.join(f'{key}={value}' for key, value in items) else: query = '' return f'postgresql:///{dbname}{query}'