Skip to content

Commit

Permalink
registries: add support for PostgreSQL-based registry
Browse files Browse the repository at this point in the history
A filename ending in ".pgsql" indicates the use of PostgreSQL. That file
should be in YAML format and contain entries to specify the use of a pgsql
database.
  • Loading branch information
PaulPrice committed May 10, 2017
1 parent 5d87b6f commit 7705d1c
Showing 1 changed file with 87 additions and 0 deletions.
87 changes: 87 additions & 0 deletions python/lsst/daf/persistence/registries.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import os
import astropy.io.fits
import re
import yaml

try:
import sqlite3
haveSqlite3 = True
Expand All @@ -52,6 +54,13 @@
except ImportError:
haveSqlite3 = False

# PostgreSQL support
try:
import psycopg2 as pgsql
havePgsql = True
except ImportError:
havePgsql = False


class Registry(object):
"""The registry base class."""
Expand All @@ -73,6 +82,9 @@ def create(location):
# if re.match(r'.*\.paf', location):
# return CalibRegistry(location)

if location.endswith(".pgsql"):
return PgsqlRegistry(location)

# look for an sqlite3 registry
if re.match(r'.*\.sqlite3', location):
if not haveSqlite3:
Expand Down Expand Up @@ -396,3 +408,78 @@ def __init__(self, location):
else:
conn = None
SqlRegistry.__init__(self, conn)


class PgsqlRegistry(SqlRegistry):
"""A PostgreSQL-based registry"""
placeHolder = "%s"

def __init__(self, location):
"""Constructor
Parameters
----------
location : `str`
Path to PostgreSQL configuration file.
"""
if not havePgsql:
raise RuntimeError("Cannot use PgsqlRegistry: could not import psycopg2")
config = self.readYaml(location)
self._config = config
conn = pgsql.connect(host=config["host"], port=config["port"], database=config["database"],
user=config["user"], password=config["password"])
SqlRegistry.__init__(self, conn)

def __del__(self):
if self.conn:
self.conn.close()

@staticmethod
def readYaml(location):
"""Read YAML configuration file
The YAML configuration file should contain:
* host : host name for database connection
* port : port for database connection
* user : user name for database connection
* database : database name
It may also contain:
* password : password for database connection
The optional entries are set to `None` in the output configuration.
Parameters
----------
location : `str`
Path to PostgreSQL YAML config file.
Returns
-------
config : `dict`
Configuration
"""
with open(location) as ff:
data = yaml.load(ff)
requireKeys = set(["host", "port", "database", "user"])
optionalKeys = set(["password"])
haveKeys = set(data.keys())
if haveKeys - optionalKeys != requireKeys:
raise RuntimeError(
"PostgreSQL YAML configuration (%s) should contain only %s, and may contain 'password', "
"but this contains: %s" %
(location, ",".join("'%s'" % key for key in requireKeys),
",".join("'%s'" % key for key in data.keys()))
)
for key in optionalKeys:
if key not in data:
data[key] = None

return data

def lookup(self, *args, **kwargs):
try:
return SqlRegistry.lookup(self, *args, **kwargs)
except Exception as exc:
self.conn.rollback()
raise

0 comments on commit 7705d1c

Please sign in to comment.