mirror of
https://github.com/sprockets/sprockets.clients.postgresql.git
synced 2024-12-26 19:34:53 +00:00
Change to URI based env var config
- Bump rev to 2.0.0 since this is backwards incompatible - Update docs - Update tests - move from FOO_HOST, FOO_PORT, etc to PGSQL_FOO=URI
This commit is contained in:
parent
86043e2733
commit
836ec3f140
6 changed files with 43 additions and 94 deletions
11
README.rst
11
README.rst
|
@ -26,8 +26,8 @@ Requirements
|
|||
|
||||
Example
|
||||
-------
|
||||
The following example sets the environment variables for connecting to
|
||||
PostgreSQL on localhost to the ``postgres`` database and issues a query.
|
||||
The following example sets the environment variable for connecting to
|
||||
PostgreSQL on localhost to the ``production`` database and issues a query.
|
||||
|
||||
.. code:: python
|
||||
|
||||
|
@ -35,12 +35,9 @@ PostgreSQL on localhost to the ``postgres`` database and issues a query.
|
|||
|
||||
from sprockets.clients import postgresql
|
||||
|
||||
os.environ['POSTGRES_HOST'] = 'localhost'
|
||||
os.environ['POSTGRES_USER'] = 'postgres'
|
||||
os.environ['POSTGRES_PORT'] = 5432
|
||||
os.environ['POSTGRES_DBNAME'] = 'postgres'
|
||||
os.environ['PGSQL_PROD'] = 'postgresql://postgres@localhost:5432/production'
|
||||
|
||||
session = postgresql.Session('postgres')
|
||||
session = postgresql.Session('prod')
|
||||
result = session.query('SELECT 1')
|
||||
print(repr(result))
|
||||
|
||||
|
|
|
@ -9,12 +9,9 @@ PostgreSQL on localhost to the ``postgres`` database and issues a query.
|
|||
|
||||
from sprockets.clients import postgresql
|
||||
|
||||
os.environ['POSTGRES_HOST'] = 'localhost'
|
||||
os.environ['POSTGRES_USER'] = 'postgres'
|
||||
os.environ['POSTGRES_PORT'] = 5432
|
||||
os.environ['POSTGRES_DBNAME'] = 'postgres'
|
||||
os.environ['PGSQL'] = 'postgresql://postgres@localhost:5432/postgres'
|
||||
|
||||
session = postgresql.Session('postgres')
|
||||
session = postgresql.Session()
|
||||
result = session.query('SELECT 1')
|
||||
print(repr(result))
|
||||
|
||||
|
@ -30,15 +27,12 @@ class in a Tornado :py:class:`RequestHandler <tornado.web.RequestHandler>`.
|
|||
from sprockets.clients import postgresql
|
||||
from tornado import web
|
||||
|
||||
os.environ['POSTGRES_HOST'] = 'localhost'
|
||||
os.environ['POSTGRES_USER'] = 'postgres'
|
||||
os.environ['POSTGRES_PORT'] = 5432
|
||||
os.environ['POSTGRES_DBNAME'] = 'postgres'
|
||||
os.environ['PGSQL_FOO'] = 'postgresql://postgres@localhost:5432/foo'
|
||||
|
||||
class RequestHandler(web.RequestHandler):
|
||||
|
||||
def initialize(self):
|
||||
self.session = postgresql.TornadoSession('postgres')
|
||||
self.session = postgresql.TornadoSession('foo')
|
||||
|
||||
@gen.coroutine
|
||||
def get(self, *args, **kwargs):
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Version History
|
||||
---------------
|
||||
- 2.0.0 [2014-10-07]
|
||||
- Change the environment variable format to be URI based instead of a variable per host, port, dbname, etc.
|
||||
- 1.0.1 [2014-09-05]
|
||||
- Expose psycopg2/queries exceptions, objects, etc from ``sprockets.queries.postgresql``
|
||||
- Add integration testing with PostgreSQL
|
||||
|
|
2
setup.py
2
setup.py
|
@ -4,7 +4,7 @@ import setuptools
|
|||
|
||||
setuptools.setup(
|
||||
name='sprockets.clients.postgresql',
|
||||
version='1.0.1',
|
||||
version='2.0.0',
|
||||
description=('PostgreSQL client library wrapper providing environment '
|
||||
'variable based configuration'),
|
||||
long_description=codecs.open('README.rst', encoding='utf-8').read(),
|
||||
|
|
|
@ -5,19 +5,18 @@ The Session classes wrap the Queries :py:class:`Session <queries.Session>` and
|
|||
:py:class:`TornadoSession <queries.tornado_session.TornadoSession>` classes
|
||||
providing environment variable based configuration.
|
||||
|
||||
The environment variables should be set using the ``DBNAME_[VARIABLE]`` format
|
||||
where ``[VARIABLE]`` is one of ``HOST``, ``PORT``, ``DBNAME``, ``USER``, and
|
||||
``PASSWORD``.
|
||||
Environment variables should be set using the ``PGSQL[_DBNAME]`` format
|
||||
where the value is a PostgreSQL URI.
|
||||
|
||||
For example, given the environment variables:
|
||||
For PostgreSQL URI format, see:
|
||||
|
||||
http://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNSTRING
|
||||
|
||||
As example, given the environment variable:
|
||||
|
||||
.. code:: python
|
||||
|
||||
FOO_HOST = 'foodb'
|
||||
FOO_PORT = '6000'
|
||||
FOO_DBNAME = 'foo'
|
||||
FOO_USER = 'bar'
|
||||
FOO_PASSWORD = 'baz'
|
||||
PGSQL_FOO = 'postgresql://bar:baz@foohost:6000/foo'
|
||||
|
||||
and code for creating a :py:class:`Session` instance for the database name
|
||||
``foo``:
|
||||
|
@ -26,11 +25,12 @@ and code for creating a :py:class:`Session` instance for the database name
|
|||
|
||||
session = sprockets.postgresql.Session('foo')
|
||||
|
||||
The uri ``postgresql://bar:baz@foodb:6000/foo`` will be used when creating the
|
||||
instance of :py:class:`queries.Session`.
|
||||
A :py:class:`queries.Session` object will be created that connects to Postgres
|
||||
running on ``foohost``, port ``6000`` using the username ``bar`` and the
|
||||
password ``baz``, connecting to the ``foo`` database.
|
||||
|
||||
"""
|
||||
version_info = (1, 0, 1)
|
||||
version_info = (2, 0, 0)
|
||||
__version__ = '.'.join(str(v) for v in version_info)
|
||||
|
||||
import logging
|
||||
|
@ -66,27 +66,21 @@ from queries import TransactionRollbackError
|
|||
|
||||
|
||||
def _get_uri(dbname):
|
||||
"""Construct the URI for connecting to PostgreSQL by appending each
|
||||
argument name to the dbname, delimited by an underscore and
|
||||
capitalizing the new variable name.
|
||||
|
||||
Values will be retrieved from the environment variable and added to a
|
||||
dictionary that is then passed in as keyword arguments to the
|
||||
:py:meth:`queries.uri` method to build the URI string.
|
||||
"""Return the URI for the specified database name from an environment
|
||||
variable. If dbname is blank, the ``PGSQL`` environment variable is used,
|
||||
otherwise the database name is cast to upper case and concatenated to
|
||||
``PGSQL_`` and the URI is retrieved from ``PGSQL_DBNAME``. For example,
|
||||
if the value ``foo`` is passed in, the environment variable used would be
|
||||
``PGSQL_FOO``.
|
||||
|
||||
:param str dbname: The database name to construct the URI for
|
||||
:return: str
|
||||
:raises: KeyError
|
||||
|
||||
"""
|
||||
kwargs = dict()
|
||||
for arg in _ARGUMENTS:
|
||||
value = os.getenv(('%s_%s' % (dbname, arg)).upper())
|
||||
if value:
|
||||
if arg == 'port':
|
||||
kwargs[arg] = int(value)
|
||||
else:
|
||||
kwargs[arg] = value
|
||||
return queries.uri(**kwargs)
|
||||
if not dbname:
|
||||
return os.environ['PGSQL']
|
||||
return os.environ['PGSQL_{0}'.format(dbname).upper()]
|
||||
|
||||
|
||||
class Session(queries.Session):
|
||||
|
|
58
tests.py
58
tests.py
|
@ -10,7 +10,6 @@ try:
|
|||
except ImportError:
|
||||
import unittest
|
||||
|
||||
from tornado import gen
|
||||
from sprockets.clients import postgresql
|
||||
import queries
|
||||
from tornado import testing
|
||||
|
@ -18,17 +17,9 @@ from tornado import testing
|
|||
|
||||
class TestGetURI(unittest.TestCase):
|
||||
|
||||
def tearDown(self):
|
||||
for key in ['HOST', 'PORT', 'DBNAME', 'USER', 'PASSWORD']:
|
||||
del os.environ['TEST1_%s' % key]
|
||||
|
||||
def test_get_uri_returns_proper_values(self):
|
||||
|
||||
os.environ['TEST1_HOST'] = 'test1-host'
|
||||
os.environ['TEST1_PORT'] = '5436'
|
||||
os.environ['TEST1_DBNAME'] = 'test1'
|
||||
os.environ['TEST1_USER'] = 'foo1'
|
||||
os.environ['TEST1_PASSWORD'] = 'baz1'
|
||||
os.environ['PGSQL_TEST1'] = \
|
||||
'postgresql://foo1:baz1@test1-host:5436/test1'
|
||||
|
||||
self.assertEqual(postgresql._get_uri('test1'),
|
||||
'postgresql://foo1:baz1@test1-host:5436/test1')
|
||||
|
@ -39,17 +30,9 @@ class TestSession(unittest.TestCase):
|
|||
@mock.patch('queries.session.Session.__init__')
|
||||
def setUp(self, mock_init):
|
||||
self.mock_init = mock_init
|
||||
os.environ['TEST2_HOST'] = 'db1'
|
||||
os.environ['TEST2_PORT'] = '5433'
|
||||
os.environ['TEST2_DBNAME'] = 'bar'
|
||||
os.environ['TEST2_USER'] = 'foo'
|
||||
os.environ['TEST2_PASSWORD'] = 'baz'
|
||||
os.environ['PGSQL_TEST2'] = 'postgresql://foo:baz@db1:5433/bar'
|
||||
self.session = postgresql.Session('test2')
|
||||
|
||||
def tearDown(self):
|
||||
for key in ['HOST', 'PORT', 'DBNAME', 'USER', 'PASSWORD']:
|
||||
del os.environ['TEST2_%s' % key]
|
||||
|
||||
def test_session_invokes_queries_session(self):
|
||||
self.assertTrue(self.mock_init.called)
|
||||
|
||||
|
@ -59,17 +42,9 @@ class TestTornadoSession(unittest.TestCase):
|
|||
@mock.patch('queries.tornado_session.TornadoSession.__init__')
|
||||
def setUp(self, mock_init):
|
||||
self.mock_init = mock_init
|
||||
os.environ['TEST3_HOST'] = 'db1'
|
||||
os.environ['TEST3_PORT'] = '5434'
|
||||
os.environ['TEST3_DBNAME'] = 'bar'
|
||||
os.environ['TEST3_USER'] = 'foo'
|
||||
os.environ['TEST3_PASSWORD'] = 'baz'
|
||||
os.environ['PGSQL_TEST3'] = 'postgresql://foo:baz@db1:5434/bar'
|
||||
self.session = postgresql.TornadoSession('test3')
|
||||
|
||||
def tearDown(self):
|
||||
for key in ['HOST', 'PORT', 'DBNAME', 'USER', 'PASSWORD']:
|
||||
del os.environ['TEST3_%s' % key]
|
||||
|
||||
def test_session_invokes_queries_session(self):
|
||||
self.assertTrue(self.mock_init.called)
|
||||
|
||||
|
@ -77,20 +52,13 @@ class TestTornadoSession(unittest.TestCase):
|
|||
class SessionIntegrationTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
os.environ['TEST4_HOST'] = 'localhost'
|
||||
os.environ['TEST4_PORT'] = '5432'
|
||||
os.environ['TEST4_DBNAME'] = 'postgres'
|
||||
os.environ['TEST4_USER'] = 'postgres'
|
||||
|
||||
os.environ['PGSQL_TEST4'] = \
|
||||
'postgresql://postgres@localhost:5432/postgres'
|
||||
try:
|
||||
self.session = postgresql.Session('test', pool_max_size=10)
|
||||
self.session = postgresql.Session('test4', pool_max_size=10)
|
||||
except postgresql.OperationalError as error:
|
||||
raise unittest.SkipTest(str(error).split('\n')[0])
|
||||
|
||||
def tearDown(self):
|
||||
for key in ['HOST', 'PORT', 'DBNAME', 'USER']:
|
||||
del os.environ['TEST4_%s' % key]
|
||||
|
||||
def test_query_returns_results_object(self):
|
||||
self.assertIsInstance(self.session.query('SELECT 1 AS value'),
|
||||
queries.Results)
|
||||
|
@ -118,18 +86,12 @@ class TornadoSessionIntegrationTests(testing.AsyncTestCase):
|
|||
|
||||
def setUp(self):
|
||||
super(TornadoSessionIntegrationTests, self).setUp()
|
||||
os.environ['TEST5_HOST'] = 'localhost'
|
||||
os.environ['TEST5_PORT'] = '5432'
|
||||
os.environ['TEST5_DBNAME'] = 'postgres'
|
||||
os.environ['TEST5_USER'] = 'postgres'
|
||||
self.session = postgresql.TornadoSession('test',
|
||||
os.environ['PGSQL_TEST5'] = \
|
||||
'postgresql://postgres@localhost:5432/postgres'
|
||||
self.session = postgresql.TornadoSession('test5',
|
||||
pool_max_size=10,
|
||||
io_loop=self.io_loop)
|
||||
|
||||
#def tearDown(self):
|
||||
# for key in ['HOST', 'PORT', 'DBNAME', 'USER']:
|
||||
# del os.environ['TEST5_%s' % key]
|
||||
|
||||
@testing.gen_test
|
||||
def test_query_returns_results_object(self):
|
||||
try:
|
||||
|
|
Loading…
Reference in a new issue