Skip to content

Commit a89f57c

Browse files
author
James William Pye
committed
Allow postgresql.open to accept keyword arguments as it should have in 0.8.
The documentation may need a little work in order to highlight the fact that it **can** take Connection Keywords. I'm not excited about mixing the locator description with connection keywords, which is why the keyword argument description was appended to the postgresql.open section.
1 parent 65f8aa3 commit a89f57c

3 files changed

Lines changed: 72 additions & 10 deletions

File tree

postgresql/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
version_info = (0, 9, 0, 'dev', 0)
3131

3232
pg_iri = pg_driver = pg_param = None
33-
def open(iri = None):
33+
def open(iri = None, **kw):
3434
"""
3535
Create a `postgresql.api.Connection` to the server referenced by the given
3636
`iri`::
@@ -48,7 +48,7 @@ def open(iri = None):
4848
(Note: "pq" is the name of the protocol used to communicate with PostgreSQL)
4949
"""
5050
global pg_iri, pg_driver, pg_param
51-
if None in (pg_iri, pg_driver, pg_param):
51+
if pg_iri is None:
5252
from . import iri as pg_iri
5353
from . import driver as pg_driver
5454
from . import clientparameters as pg_param
@@ -66,7 +66,8 @@ def open(iri = None):
6666
std_params = pg_param.collect(prompt_title = None)
6767
params = pg_param.normalize(
6868
list(pg_param.denormalize_parameters(std_params)) + \
69-
list(pg_param.denormalize_parameters(iri_params))
69+
list(pg_param.denormalize_parameters(iri_params)) + \
70+
list(pg_param.denormalize_parameters(kw))
7071
)
7172
# Resolve the password, but never prompt.
7273
pg_param.resolve_password(params, prompt_title = None)

postgresql/documentation/driver.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@
5454
-----------------
5555
5656
In the root package module, the ``open()`` function is provided for accessing
57-
databases using a single locator string. The string taken by `postgresql.open` is
58-
a URL whose components make up the client parameters::
57+
databases using a locator string and optional connection keywords. The string
58+
taken by `postgresql.open` is a URL whose components make up the client
59+
parameters::
5960
6061
>>> import postgresql
6162
>>> db = postgresql.open("pq://localhost/postgres")
@@ -64,14 +65,14 @@
6465
``postgres`` via the ``pq`` protocol. open will inherit client parameters from
6566
the environment, so the user name given to the server will come from
6667
``$PGUSER``, or if that is unset, the result of `getpass.getuser`--the username
67-
of the user running the process. The user's "pgpassfile" will also be
68+
of the user running the process. The user's "pgpassfile" will even be
6869
referenced if no password is given::
6970
7071
>>> db = postgresql.open("pq://username:password@localhost/postgres")
7172
72-
In this case, the password is given, so ``~/.pgpass`` would never be referenced.
73-
The ``user`` client parameter is also given, ``username``, so ``$PGUSER`` or
74-
`getpass.getuser` will not be given to the server.
73+
In this case, the password *is* given, so ``~/.pgpass`` would never be
74+
referenced. The ``user`` client parameter is also given, ``username``, so
75+
``$PGUSER`` or `getpass.getuser` will not be given to the server.
7576
7677
Settings can also be provided by the query portion of the URL::
7778
@@ -92,11 +93,30 @@
9293
9394
protocol://user:password@host:port/database?[driver_setting]=value&server_setting=value#schema,public
9495
95-
For more information about environment variables, see :doc:`Environment
96+
Optionally, connection keyword arguments can be used to override anything given
97+
in the locator::
98+
99+
>>> db = postgresql.open("pq://user:secret@host", password = "thE_real_sekrat")
100+
101+
Or, if the locator is not desired, individual keywords can be used exclusively::
102+
103+
>>> db = postgresql.open(user = 'user', host = 'localhost', port = 6543)
104+
105+
In fact, all arguments to `postgresql.open` are optional as all arguments are
106+
keywords; ``iri`` is merely the first keyword argument taken by
107+
`postgresql.open`. If the environment has all the necessary parameters for a
108+
successful connection, there is no need to pass anything to open::
109+
110+
>>> db = postgresql.open()
111+
112+
For a complete list of keywords that `postgresql.open` can accept, see
113+
`Connection Keywords`_.
114+
For more information about the environment variables, see :doc:`Environment
96115
Variables</clientparameters>`.
97116
For more information about the ``pgpassfile``, see :doc:`PostgreSQL Password
98117
File</clientparameters>`.
99118
119+
100120
`postgresql.driver.connect`
101121
---------------------------
102122

postgresql/test/test_connect.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,47 @@ def test_pg_open_SQL_ASCII(self):
8484
self.failUnlessEqual(db.settings['client_encoding'], 'SQL_ASCII')
8585
self.failUnless(db.closed)
8686

87+
def test_pg_open_keywords(self):
88+
host, port = self.cluster.address()
89+
# straight test, no IRI
90+
with pg_open(
91+
user = 'md5',
92+
password = 'md5_password',
93+
host = host,
94+
port = port,
95+
database = 'test'
96+
) as db:
97+
self.failUnlessEqual(db.prepare('select 1')(), [(1,)])
98+
self.failUnless(db.closed)
99+
# composite test
100+
with pg_open(
101+
"pq://md5:md5_password@",
102+
host = host,
103+
port = port,
104+
database = 'test'
105+
) as db:
106+
self.failUnlessEqual(db.prepare('select 1')(), [(1,)])
107+
# override test
108+
with pg_open(
109+
"pq://md5:foobar@",
110+
password = 'md5_password',
111+
host = host,
112+
port = port,
113+
database = 'test'
114+
) as db:
115+
self.failUnlessEqual(db.prepare('select 1')(), [(1,)])
116+
# and, one with some settings
117+
with pg_open(
118+
"pq://md5:foobar@?search_path=ieeee",
119+
password = 'md5_password',
120+
host = host,
121+
port = port,
122+
database = 'test',
123+
settings = {'search_path' : 'public'}
124+
) as db:
125+
self.failUnlessEqual(db.prepare('select 1')(), [(1,)])
126+
self.failUnlessEqual(db.settings['search_path'], 'public')
127+
87128
def test_pg_open(self):
88129
# postgresql.open
89130
host, port = self.cluster.address()

0 commit comments

Comments
 (0)