exceptable - exception propagation for pg

53
Exceptable Tuesday, October 20, 2009

Upload: command-prompt-inc

Post on 19-May-2015

525 views

Category:

Documents


2 download

DESCRIPTION

Aurynn ShawThis talk discusses Exceptable, a sane exception propagation framework for PG 8.3 and above. We will be covering the need for coherent exception propagation in stored-procedure-based applications, how exceptions are handled in PG 8.3, the tools 8.4 brings regarding raising exceptions from PL/PGSQL, and how a consistent exception model benefits architectures heavily invested in stored procedures. Finally, we will discuss Exceptable, a PL/PGSQL and Python API for consistent handling of exceptions from the Database to the Application Layer.

TRANSCRIPT

Page 1: Exceptable - Exception Propagation for PG

Exceptable

Tuesday, October 20, 2009

Page 2: Exceptable - Exception Propagation for PG

Exception Propagation, in PostgreSQL and PythonAurynn Shaw, Commandprompt, Inc.

PostgreSQL Conference West, 2009

Tuesday, October 20, 2009

Page 3: Exceptable - Exception Propagation for PG

Background

• Large, enterprise Python + Pylons application

• Simpycity ORM utilizes significant stored procedures

• Strong procedural interfaces

Tuesday, October 20, 2009

Page 4: Exceptable - Exception Propagation for PG

Stored Procedures are Rare

• Most people don’t use Stored Procedures.

Tuesday, October 20, 2009

Page 5: Exceptable - Exception Propagation for PG

The Present SystemWherein

• A Database Query

• A Stored Procedure

• Or, A Database Query

• Exceptions Galore

Tuesday, October 20, 2009

Page 6: Exceptable - Exception Propagation for PG

A Database Query

•The App queries the Database

Tuesday, October 20, 2009

Page 7: Exceptable - Exception Propagation for PG

A Database Query

• The App queries the Database

• Any variety of query

Tuesday, October 20, 2009

Page 8: Exceptable - Exception Propagation for PG

A Database Query

>>> c.Raw("SELECT * FROM auth_only")()

Traceback (most recent call last):

... <SNIP> ...

psycopg2.ProgrammingError: permission denied for relation auth_only

Tuesday, October 20, 2009

Page 9: Exceptable - Exception Propagation for PG

A Database Query

• The App queries the Database

• Any variety of query

• Or A Stored Procedure

Tuesday, October 20, 2009

Page 10: Exceptable - Exception Propagation for PG

Or a Stored Procedure

CREATE OR REPLACE FUNCTION except_test() RETURNS VOID AS $$

BEGIN

RAISE EXCEPTION 'Test!';

END;

$$ LANGUAGE PLPGSQL;

>>> c.Function("except_test")()

Traceback (most recent call last):

... <SNIP> ...

psycopg2.InternalError: Test!

Tuesday, October 20, 2009

Page 11: Exceptable - Exception Propagation for PG

Beget an Exception

• Stored procedures raise InternalErrors

• Every procedural exception becomes this

• Permissions violations raise ProgrammingErrors

• I haven’t tested if this is all PG exceptions.

Tuesday, October 20, 2009

Page 12: Exceptable - Exception Propagation for PG

Seriously?

• This is what we have to work with?

Tuesday, October 20, 2009

Page 13: Exceptable - Exception Propagation for PG

Why this is ImportantWherein

• Why?

• Defining your APIs

• Separation of Concerns

• Procedural Spaghetti

Tuesday, October 20, 2009

Page 14: Exceptable - Exception Propagation for PG

Why?

• Limited information to propagate upwards

• Stored Procedures are Harder to use

• Permissions violations are difficult to detect

Tuesday, October 20, 2009

Page 15: Exceptable - Exception Propagation for PG

API Undefined

• Exceptions are part of your API

Tuesday, October 20, 2009

Page 16: Exceptable - Exception Propagation for PG

API Undefined

• Exceptions are part of your API

• Easily overlooked

Tuesday, October 20, 2009

Page 17: Exceptable - Exception Propagation for PG

API Undefined

• Exceptions are part of your API

• Easily overlooked

• Delineations will make life easier

Tuesday, October 20, 2009

Page 18: Exceptable - Exception Propagation for PG

Separation of Concerns

• The Database is for Database Logic

Tuesday, October 20, 2009

Page 19: Exceptable - Exception Propagation for PG

Separation of Concerns

• The Database is for Database Logic

• Harder to write Data Logic

Tuesday, October 20, 2009

Page 20: Exceptable - Exception Propagation for PG

Spaghetti

• InternalErrors everywhere

Early version of our app didn’t have Exceptable - we were left catching InternalErrors and guessing at what the error was, based on timing.

Tuesday, October 20, 2009

Page 21: Exceptable - Exception Propagation for PG

Spaghetti

• InternalErrors everywhere

• Insufficiency of Information

Tuesday, October 20, 2009

Page 22: Exceptable - Exception Propagation for PG

Spaghetti

• InternalErrors everywhere

• Insufficiency of Information

• Considerable Repeated Code

Tuesday, October 20, 2009

Page 23: Exceptable - Exception Propagation for PG

A Saving Grace

• Violating Procedure Signatures -> Python DataError

Tuesday, October 20, 2009

Page 24: Exceptable - Exception Propagation for PG

A Better DealWherein

• Database API

• Easy Python implementation

• Universality

• Exceptable

Tuesday, October 20, 2009

Page 25: Exceptable - Exception Propagation for PG

Database API

• Easier to define an API

Tuesday, October 20, 2009

Page 26: Exceptable - Exception Propagation for PG

Database API

• Easier to define an API

• The DB becomes part of that API

Tuesday, October 20, 2009

Page 27: Exceptable - Exception Propagation for PG

Database API

• Easier to define an API

• The DB becomes part of that API

• Simple Stored Procedure interface

Tuesday, October 20, 2009

Page 28: Exceptable - Exception Propagation for PG

Database API

• Easier to define an API

• The DB becomes part of that API

• Simple Stored Procedure interface

• Easily declare new Exceptions

Tuesday, October 20, 2009

Page 29: Exceptable - Exception Propagation for PG

Wonderfully Python

• A Simple Decorator

Tuesday, October 20, 2009

Page 30: Exceptable - Exception Propagation for PG

Simply Decorated

from exceptable.exceptable import Except

base = Except()

@base

def db_function():

pass

Tuesday, October 20, 2009

Page 31: Exceptable - Exception Propagation for PG

Wonderfully Python

• A Simple Decorator

• Catches and re-emits Exceptions

• The core of Exceptable

• Easy to Integrate - 2 lines, in Simpycity

Tuesday, October 20, 2009

Page 32: Exceptable - Exception Propagation for PG

Universality

• Exceptable Procedures never change

• DB logic doesn’t change

• Application support is Easy

Tuesday, October 20, 2009

Page 33: Exceptable - Exception Propagation for PG

Exceptable

• More Pythonic Database Access

• Better exceptions means better app flow

Tuesday, October 20, 2009

Page 34: Exceptable - Exception Propagation for PG

Example CodeWherein

• The DB Library

• The Application Implementation

• Catching Permissions Violations

• PostgreSQL 8.4

Tuesday, October 20, 2009

Page 35: Exceptable - Exception Propagation for PG

To Start,

CREATE TABLE exceptions (

name text primary key,

description text not null,

parent text references exceptions(name)

);

INSERT INTO exceptions VALUES ('Exception', 'Base exception',NULL);

INSERT INTO exceptions VALUES ('NotFoundException', 'Could not find specified record', 'Exception');

Tuesday, October 20, 2009

Page 36: Exceptable - Exception Propagation for PG

Which leads to

CREATE OR REPLACE FUNCTION not_found ( in_reason TEXT) RETURNS VOID as $body$

SELECT exceptaple.raise( 'NotFoundException', $1 );

$body$ LANGUAGE SQL;

Tuesday, October 20, 2009

Page 37: Exceptable - Exception Propagation for PG

Application Level

• Easy to Query the Exception tables

Tuesday, October 20, 2009

Page 38: Exceptable - Exception Propagation for PG

Application Level

• Easy to Query the Exception tables

• Easy to set up a new library

• Python took 50 lines

Tuesday, October 20, 2009

Page 39: Exceptable - Exception Propagation for PG

Our Python Example

• The Exceptable decorator is easy to set up

• Designed for DB-API integration

Tuesday, October 20, 2009

Page 40: Exceptable - Exception Propagation for PG

In the Application

base = Except(InternalError, { 'Exception': Exception, 'NotFoundException': NotFoundError,})

Tuesday, October 20, 2009

Page 41: Exceptable - Exception Propagation for PG

Our Python Example

• The Exceptable decorator is easy to set up

• Designed for DB-API integration

• User-defined

Tuesday, October 20, 2009

Page 42: Exceptable - Exception Propagation for PG

User Definitions

base = Except(InternalError, {

'PermissionError': PermissionError,

'UnknownUser': UnknownUserError,

'NotFoundException': NotFoundError,

})

Tuesday, October 20, 2009

Page 43: Exceptable - Exception Propagation for PG

Our Python Example

• The Exceptable decorator is easy to set up

• Designed for DB-API integration

• User-defined, and soon, table introspection

Tuesday, October 20, 2009

Page 44: Exceptable - Exception Propagation for PG

base is a decorator

@basedef db_api(query): con = db.connect(conn_string) cur = con.cursor() return cur(query)

Tuesday, October 20, 2009

Page 45: Exceptable - Exception Propagation for PG

Which leads to

try: rs = db_api(‘select * from test_api()’)except NotFoundError, e: # A hah! A usable error! pass

Tuesday, October 20, 2009

Page 46: Exceptable - Exception Propagation for PG

As Opposed To

try: rs = db_api(‘select * from test_api()’)except InternalError, e: if “NotFoundException” in str(e): raise NotFoundError(str(e)) elif “PermissionsError” in str(e): raise PermissionsError(str(e))

Tuesday, October 20, 2009

Page 47: Exceptable - Exception Propagation for PG

Our Python Example

• The Exceptable decorator is easy to set up

• Designed for DB-API integration

• User-defined, and soon, table introspection

• Existing decorators can be expanded easily

Tuesday, October 20, 2009

Page 48: Exceptable - Exception Propagation for PG

Grow, my Pretties!

class NotNullError(BaseException): passclass SCE(BaseException): pass

base.add({‘NotNullException’: NotNullError,‘SufficientCoffeeException’: SCE

})

Tuesday, October 20, 2009

Page 49: Exceptable - Exception Propagation for PG

Permission Denied

• Exceptable.py also wraps the base permission denied

• DB permissions violations work at the app level

Tuesday, October 20, 2009

Page 50: Exceptable - Exception Propagation for PG

Vertically Challenged

a = c.Function(‘test_auth’);try: result = a()except PermissionDenied, e: abort(403)except NoSuchUser, e: abort(401)

Tuesday, October 20, 2009

Page 51: Exceptable - Exception Propagation for PG

AND THUSQuestions?

Tuesday, October 20, 2009

Page 53: Exceptable - Exception Propagation for PG

THANK YOU!

Tuesday, October 20, 2009