Top Banner
Exceptable Tuesday, October 20, 2009
53

Exceptable - Exception Propagation for PG

May 19, 2015

Download

Documents

Aurynn Shaw

This 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.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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