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