It looks like a number of people have done something similar so though I would mention my attempt - pgwrap [1][2]. This is also a thin wrapper over psycopg2. This provides the following -
* Simplified handling of connections/cursor
* Connection pool (provided by psycopg2.pool)
* Cursor context handler
* Python API to wrap basic SQL functionality
* Simple select,update,delete,join methods extending the cursor
context handler (also available as stand-alone methods which
create an implicit cursor for simple queries)
* Query results as dict (using psycopg2.extras.DictCursor or any other PG Cursor factory)
* Callable prepared statements
* Logging support
Essentially you can do stuff like: >>> import pgwrap
>>> db = pgwrap.connection(url='postgres://localhost')
>>> with db.cursor() as c:
... c.query('select version()')
[['PostgreSQL...']]
>>> v = db.query_one('select version()')
>>> v
['PostgreSQL...']
>>> v.items()
[('version', 'PostgreSQL...')]
>>> v['version']
'PostgreSQL...'
>>> db.create_table('t1','id serial,name text,count int')
>>> db.create_table('t2','id serial,t1_id int,value text')
>>> db.log = sys.stdout
>>> db.insert('t1',{'name':'abc','count':0},returning='id,name')
INSERT INTO t1 (name) VALUES ('abc') RETURNING id,name
[1, 'abc']
>>> db.insert('t2',{'t1_id':1,'value':'t2'})
INSERT INTO t2 (t1_id,value) VALUES (1,'t2')
1
>>> db.select('t1')
SELECT * FROM t1
[[1, 'abc', 0]]
>>> db.select_one('t1',where={'name':'abc'},columns=('name','count'))
SELECT name, count FROM t1 WHERE name = 'abc'
['abc', 0]
>>> db.join(('t1','t2'),columns=('t1.id','t2.value'))
SELECT t1.id, t2.value FROM t1 JOIN t2 ON t1.id = t2.t1_id
[[1, 't2']]
>>> db.insert('t1',{'name':'abc'},returning='id')
INSERT INTO t1 (name) VALUES ('abc') RETURNING id
[2]
>>> db.update('t1',{'name':'xyz'},where={'name':'abc'})
UPDATE t1 SET name = 'xyz' WHERE name = 'abc'
2
>>> db.update('t1',{'count__func':'count + 1'},where= {'count__lt':10},returning="id,count")
UPDATE t1 SET count = count + 1 WHERE count < 10 RETURNING id,count
[[1, 1]]
Also it allows you to create callable prepared statements (which I find really useful in structuring apps): >>> update_t1_name = db.prepare('UPDATE t1 SET name = $2 WHERE id = $1')
PREPARE stmt_001 AS UPDATE t1 SET name = $2 WHERE id = $1
>>> update_t1_name(1,'xxx')
EXECUTE _pstmt_001 (1,'xxx')
[1] https://github.com/paulchakravarti/pgwrap
[2] https://pypi.python.org/pypi/pgwrap