exceptable

53
Exceptable Tuesday, October 20, 2009

Upload: aurynn-shaw

Post on 24-Apr-2015

1.489 views

Category:

Technology


0 download

DESCRIPTION

Exceptable - Useful database stored procedure exceptions in your application layer.

TRANSCRIPT

Page 1: Exceptable

Exceptable

Tuesday, October 20, 2009

Page 2: Exceptable

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

PostgreSQL Conference West, 2009

Tuesday, October 20, 2009

Page 3: Exceptable

Background

• Large, enterprise Python + Pylons application

• Simpycity ORM utilizes significant stored procedures

• Strong procedural interfaces

Tuesday, October 20, 2009

Page 4: Exceptable

Stored Procedures are Rare

• Most people don’t use Stored Procedures.

Tuesday, October 20, 2009

Page 5: Exceptable

The Present SystemWherein

• A Database Query

• A Stored Procedure

• Or, A Database Query

• Exceptions Galore

Tuesday, October 20, 2009

Page 6: Exceptable

A Database Query

•The App queries the Database

Tuesday, October 20, 2009

Page 7: Exceptable

A Database Query

• The App queries the Database

• Any variety of query

Tuesday, October 20, 2009

Page 8: Exceptable

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

A Database Query

• The App queries the Database

• Any variety of query

• Or A Stored Procedure

Tuesday, October 20, 2009

Page 10: Exceptable

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

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

Seriously?

• This is what we have to work with?

Tuesday, October 20, 2009

Page 13: Exceptable

Why this is ImportantWherein

• Why?

• Defining your APIs

• Separation of Concerns

• Procedural Spaghetti

Tuesday, October 20, 2009

Page 14: Exceptable

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

API Undefined

• Exceptions are part of your API

Tuesday, October 20, 2009

Page 16: Exceptable

API Undefined

• Exceptions are part of your API

• Easily overlooked

Tuesday, October 20, 2009

Page 17: Exceptable

API Undefined

• Exceptions are part of your API

• Easily overlooked

• Delineations will make life easier

Tuesday, October 20, 2009

Page 18: Exceptable

Separation of Concerns

• The Database is for Database Logic

Tuesday, October 20, 2009

Page 19: Exceptable

Separation of Concerns

• The Database is for Database Logic

• Harder to write Data Logic

Tuesday, October 20, 2009

Page 20: Exceptable

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

Spaghetti

• InternalErrors everywhere

• Insufficiency of Information

Tuesday, October 20, 2009

Page 22: Exceptable

Spaghetti

• InternalErrors everywhere

• Insufficiency of Information

• Considerable Repeated Code

Tuesday, October 20, 2009

Page 23: Exceptable

A Saving Grace

• Violating Procedure Signatures -> Python DataError

Tuesday, October 20, 2009

Page 24: Exceptable

A Better DealWherein

• Database API

• Easy Python implementation

• Universality

• Exceptable

Tuesday, October 20, 2009

Page 25: Exceptable

Database API

• Easier to define an API

Tuesday, October 20, 2009

Page 26: Exceptable

Database API

• Easier to define an API

• The DB becomes part of that API

Tuesday, October 20, 2009

Page 27: Exceptable

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

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

Wonderfully Python

• A Simple Decorator

Tuesday, October 20, 2009

Page 30: Exceptable

Simply Decorated

from exceptable.exceptable import Except

base = Except()

@base

def db_function():

pass

Tuesday, October 20, 2009

Page 31: Exceptable

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

Universality

• Exceptable Procedures never change

• DB logic doesn’t change

• Application support is Easy

Tuesday, October 20, 2009

Page 33: Exceptable

Exceptable

• More Pythonic Database Access

• Better exceptions means better app flow

Tuesday, October 20, 2009

Page 34: Exceptable

Example CodeWherein

• The DB Library

• The Application Implementation

• Catching Permissions Violations

• PostgreSQL 8.4

Tuesday, October 20, 2009

Page 35: Exceptable

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

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

Application Level

• Easy to Query the Exception tables

Tuesday, October 20, 2009

Page 38: Exceptable

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

Our Python Example

• The Exceptable decorator is easy to set up

• Designed for DB-API integration

Tuesday, October 20, 2009

Page 40: Exceptable

In the Application

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

Tuesday, October 20, 2009

Page 41: Exceptable

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

User Definitions

base = Except(InternalError, {

'PermissionError': PermissionError,

'UnknownUser': UnknownUserError,

'NotFoundException': NotFoundError,

})

Tuesday, October 20, 2009

Page 43: Exceptable

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

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

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

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

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

Grow, my Pretties!

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

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

})

Tuesday, October 20, 2009

Page 49: Exceptable

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

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

AND THUSQuestions?

Tuesday, October 20, 2009

Page 53: Exceptable

THANK YOU!

Tuesday, October 20, 2009