SlideShare ist ein Scribd-Unternehmen logo
1 von 53
Downloaden Sie, um offline zu lesen
Exceptable



Tuesday, October 20, 2009
Exception Propagation, in
                     PostgreSQL and Python
                        Aurynn Shaw, Commandprompt, Inc.



                             PostgreSQL Conference West, 2009

Tuesday, October 20, 2009
Background


     • Large, enterprise Python + Pylons application
     • Simpycity ORM utilizes significant stored
           procedures

             • Strong procedural interfaces



Tuesday, October 20, 2009
Stored Procedures are Rare



             • Most people don’t use Stored Procedures.




Tuesday, October 20, 2009
The Present System
                              Wherein


        • A Database Query
        • A Stored Procedure
        • Or, A Database Query
        • Exceptions Galore



Tuesday, October 20, 2009
A Database Query



     • The App queries the Database




Tuesday, October 20, 2009
A Database Query



     • The App queries the Database
     • Any variety of query




Tuesday, October 20, 2009
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
A Database Query


     • The App queries the Database
     • Any variety of query
     • Or A Stored Procedure



Tuesday, October 20, 2009
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
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
Seriously?



     • This is what we have to work with?




Tuesday, October 20, 2009
Why this is Important
                            Wherein


        • Why?
        • Defining your APIs
        • Separation of Concerns
        • Procedural Spaghetti



Tuesday, October 20, 2009
Why?


     • Limited information to propagate upwards
     • Stored Procedures are Harder to use
     • Permissions violations are difficult to detect



Tuesday, October 20, 2009
API Undefined



     • Exceptions are part of your API




Tuesday, October 20, 2009
API Undefined



     • Exceptions are part of your API
     • Easily overlooked




Tuesday, October 20, 2009
API Undefined


     • Exceptions are part of your API
     • Easily overlooked
     • Delineations will make life easier



Tuesday, October 20, 2009
Separation of Concerns



     • The Database is for Database Logic




Tuesday, October 20, 2009
Separation of Concerns



     • The Database is for Database Logic
     • Harder to write Data Logic




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




Tuesday, October 20, 2009
Spaghetti



     • InternalErrors everywhere
     • Insufficiency of Information




Tuesday, October 20, 2009
Spaghetti


     • InternalErrors everywhere
     • Insufficiency of Information
     • Considerable Repeated Code



Tuesday, October 20, 2009
A Saving Grace



     • Violating Procedure Signatures ->
                Python DataError




Tuesday, October 20, 2009
A Better Deal
                               Wherein


        • Database API
        • Easy Python implementation
        • Universality
        • Exceptable



Tuesday, October 20, 2009
Database API



     • Easier to define an API




Tuesday, October 20, 2009
Database API



     • Easier to define an API
     • The DB becomes part of that API




Tuesday, October 20, 2009
Database API


     • Easier to define an API
     • The DB becomes part of that API
     • Simple Stored Procedure interface



Tuesday, October 20, 2009
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
Wonderfully Python



     • A Simple Decorator




Tuesday, October 20, 2009
Simply Decorated
       from exceptable.exceptable import Except


       base = Except()


       @base
       def db_function():
            pass




Tuesday, October 20, 2009
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
Universality


     • Exceptable Procedures never change
     • DB logic doesn’t change
     • Application support is Easy



Tuesday, October 20, 2009
Exceptable



     • More Pythonic Database Access
     • Better exceptions means better app flow




Tuesday, October 20, 2009
Example Code
                               Wherein


        • The DB Library
        • The Application Implementation
        • Catching Permissions Violations
        • PostgreSQL 8.4



Tuesday, October 20, 2009
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
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
Application Level



     • Easy to Query the Exception tables




Tuesday, October 20, 2009
Application Level


     • Easy to Query the Exception tables
     • Easy to set up a new library
             • Python took 50 lines



Tuesday, October 20, 2009
Our Python Example



     • The Exceptable decorator is easy to set up
     • Designed for DB-API integration




Tuesday, October 20, 2009
In the Application
     base = Except(InternalError, {
         'Exception': Exception,
         'NotFoundException': NotFoundError,
     })




Tuesday, October 20, 2009
Our Python Example


     • The Exceptable decorator is easy to set up
     • Designed for DB-API integration
     • User-defined



Tuesday, October 20, 2009
User Definitions
       base = Except(InternalError, {
           'PermissionError': PermissionError,
           'UnknownUser': UnknownUserError,
           'NotFoundException': NotFoundError,
       })




Tuesday, October 20, 2009
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
base is a decorator
     @base
     def db_api(query):
       con = db.connect(conn_string)
       cur = con.cursor()
       return cur(query)




Tuesday, October 20, 2009
Which leads to
     try:
       rs = db_api(‘select * from test_api()’)
     except NotFoundError, e:
       # A hah! A usable error!
       pass




Tuesday, October 20, 2009
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
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
Grow, my Pretties!
     class NotNullError(BaseException):
       pass
     class SCE(BaseException):
       pass

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


Tuesday, October 20, 2009
Permission Denied


     • Exceptable.py also wraps the base permission
           denied

     • DB permissions violations work at the app level



Tuesday, October 20, 2009
Vertically Challenged
     a = c.Function(‘test_auth’);
     try:
       result = a()
     except PermissionDenied, e:
       abort(403)
     except NoSuchUser, e:
       abort(401)




Tuesday, October 20, 2009
AND THUS
                             Questions?




Tuesday, October 20, 2009
Get It!

  https://projects.commandprompt.com/
            public/exceptable/




Tuesday, October 20, 2009
THANK YOU!



Tuesday, October 20, 2009

Weitere ähnliche Inhalte

Andere mochten auch

Building tungsten-clusters-with-postgre sql-hot-standby-and-streaming-replica...
Building tungsten-clusters-with-postgre sql-hot-standby-and-streaming-replica...Building tungsten-clusters-with-postgre sql-hot-standby-and-streaming-replica...
Building tungsten-clusters-with-postgre sql-hot-standby-and-streaming-replica...Command Prompt., Inc
 
Replication using PostgreSQL Replicator
Replication using PostgreSQL ReplicatorReplication using PostgreSQL Replicator
Replication using PostgreSQL ReplicatorCommand Prompt., Inc
 
configuring a warm standby, the easy way
configuring a warm standby, the easy wayconfiguring a warm standby, the easy way
configuring a warm standby, the easy wayCommand Prompt., Inc
 
Implementing the Future of PostgreSQL Clustering with Tungsten
Implementing the Future of PostgreSQL Clustering with TungstenImplementing the Future of PostgreSQL Clustering with Tungsten
Implementing the Future of PostgreSQL Clustering with TungstenCommand Prompt., Inc
 
Python utilities for data presentation
Python utilities for data presentationPython utilities for data presentation
Python utilities for data presentationCommand Prompt., Inc
 
Elephant Roads: a tour of Postgres forks
Elephant Roads: a tour of Postgres forksElephant Roads: a tour of Postgres forks
Elephant Roads: a tour of Postgres forksCommand Prompt., Inc
 
Howdah - An Application using Pylons, PostgreSQL, Simpycity and Exceptable
Howdah - An Application using Pylons, PostgreSQL, Simpycity and ExceptableHowdah - An Application using Pylons, PostgreSQL, Simpycity and Exceptable
Howdah - An Application using Pylons, PostgreSQL, Simpycity and ExceptableCommand Prompt., Inc
 
PostgreSQL Administration for System Administrators
PostgreSQL Administration for System AdministratorsPostgreSQL Administration for System Administrators
PostgreSQL Administration for System AdministratorsCommand Prompt., Inc
 
Postgres in Production - Best Practices 2014
Postgres in Production - Best Practices 2014Postgres in Production - Best Practices 2014
Postgres in Production - Best Practices 2014EDB
 
PostgreSQL - El camino de la disponibilidad
PostgreSQL - El camino de la disponibilidadPostgreSQL - El camino de la disponibilidad
PostgreSQL - El camino de la disponibilidadLenin Hernandez
 

Andere mochten auch (17)

Building tungsten-clusters-with-postgre sql-hot-standby-and-streaming-replica...
Building tungsten-clusters-with-postgre sql-hot-standby-and-streaming-replica...Building tungsten-clusters-with-postgre sql-hot-standby-and-streaming-replica...
Building tungsten-clusters-with-postgre sql-hot-standby-and-streaming-replica...
 
Replication using PostgreSQL Replicator
Replication using PostgreSQL ReplicatorReplication using PostgreSQL Replicator
Replication using PostgreSQL Replicator
 
configuring a warm standby, the easy way
configuring a warm standby, the easy wayconfiguring a warm standby, the easy way
configuring a warm standby, the easy way
 
Backup and-recovery2
Backup and-recovery2Backup and-recovery2
Backup and-recovery2
 
Go replicator
Go replicatorGo replicator
Go replicator
 
Pg migrator
Pg migratorPg migrator
Pg migrator
 
Implementing the Future of PostgreSQL Clustering with Tungsten
Implementing the Future of PostgreSQL Clustering with TungstenImplementing the Future of PostgreSQL Clustering with Tungsten
Implementing the Future of PostgreSQL Clustering with Tungsten
 
Python utilities for data presentation
Python utilities for data presentationPython utilities for data presentation
Python utilities for data presentation
 
A Practical Multi-Tenant Cluster
A Practical Multi-Tenant ClusterA Practical Multi-Tenant Cluster
A Practical Multi-Tenant Cluster
 
Temporal Data
Temporal DataTemporal Data
Temporal Data
 
Elephant Roads: a tour of Postgres forks
Elephant Roads: a tour of Postgres forksElephant Roads: a tour of Postgres forks
Elephant Roads: a tour of Postgres forks
 
Howdah - An Application using Pylons, PostgreSQL, Simpycity and Exceptable
Howdah - An Application using Pylons, PostgreSQL, Simpycity and ExceptableHowdah - An Application using Pylons, PostgreSQL, Simpycity and Exceptable
Howdah - An Application using Pylons, PostgreSQL, Simpycity and Exceptable
 
Introduction to triggers
Introduction to triggersIntroduction to triggers
Introduction to triggers
 
PostgreSQL Administration for System Administrators
PostgreSQL Administration for System AdministratorsPostgreSQL Administration for System Administrators
PostgreSQL Administration for System Administrators
 
Postgres in Production - Best Practices 2014
Postgres in Production - Best Practices 2014Postgres in Production - Best Practices 2014
Postgres in Production - Best Practices 2014
 
PostgreSQL - El camino de la disponibilidad
PostgreSQL - El camino de la disponibilidadPostgreSQL - El camino de la disponibilidad
PostgreSQL - El camino de la disponibilidad
 
5 Steps to PostgreSQL Performance
5 Steps to PostgreSQL Performance5 Steps to PostgreSQL Performance
5 Steps to PostgreSQL Performance
 

Mehr von Command Prompt., Inc

Normalization: A Workshop for Everybody Pt. 2
Normalization: A Workshop for Everybody Pt. 2Normalization: A Workshop for Everybody Pt. 2
Normalization: A Workshop for Everybody Pt. 2Command Prompt., Inc
 
Normalization: A Workshop for Everybody Pt. 1
Normalization: A Workshop for Everybody Pt. 1Normalization: A Workshop for Everybody Pt. 1
Normalization: A Workshop for Everybody Pt. 1Command Prompt., Inc
 
Integrating PostGIS in Web Applications
Integrating PostGIS in Web ApplicationsIntegrating PostGIS in Web Applications
Integrating PostGIS in Web ApplicationsCommand Prompt., Inc
 
Postgres for MySQL (and other database) people
Postgres for MySQL (and other database) peoplePostgres for MySQL (and other database) people
Postgres for MySQL (and other database) peopleCommand Prompt., Inc
 
Building Grails applications with PostgreSQL
Building Grails applications with PostgreSQLBuilding Grails applications with PostgreSQL
Building Grails applications with PostgreSQLCommand Prompt., Inc
 
Not Just UNIQUE: Exclusion Constraints
Not Just UNIQUE: Exclusion ConstraintsNot Just UNIQUE: Exclusion Constraints
Not Just UNIQUE: Exclusion ConstraintsCommand Prompt., Inc
 
pg_proctab: Accessing System Stats in PostgreSQL
pg_proctab: Accessing System Stats in PostgreSQLpg_proctab: Accessing System Stats in PostgreSQL
pg_proctab: Accessing System Stats in PostgreSQLCommand Prompt., Inc
 

Mehr von Command Prompt., Inc (10)

Normalization: A Workshop for Everybody Pt. 2
Normalization: A Workshop for Everybody Pt. 2Normalization: A Workshop for Everybody Pt. 2
Normalization: A Workshop for Everybody Pt. 2
 
Normalization: A Workshop for Everybody Pt. 1
Normalization: A Workshop for Everybody Pt. 1Normalization: A Workshop for Everybody Pt. 1
Normalization: A Workshop for Everybody Pt. 1
 
Integrating PostGIS in Web Applications
Integrating PostGIS in Web ApplicationsIntegrating PostGIS in Web Applications
Integrating PostGIS in Web Applications
 
Postgres for MySQL (and other database) people
Postgres for MySQL (and other database) peoplePostgres for MySQL (and other database) people
Postgres for MySQL (and other database) people
 
Building Grails applications with PostgreSQL
Building Grails applications with PostgreSQLBuilding Grails applications with PostgreSQL
Building Grails applications with PostgreSQL
 
Pg amqp
Pg amqpPg amqp
Pg amqp
 
Not Just UNIQUE: Exclusion Constraints
Not Just UNIQUE: Exclusion ConstraintsNot Just UNIQUE: Exclusion Constraints
Not Just UNIQUE: Exclusion Constraints
 
pg_proctab: Accessing System Stats in PostgreSQL
pg_proctab: Accessing System Stats in PostgreSQLpg_proctab: Accessing System Stats in PostgreSQL
pg_proctab: Accessing System Stats in PostgreSQL
 
Database Hardware Benchmarking
Database Hardware BenchmarkingDatabase Hardware Benchmarking
Database Hardware Benchmarking
 
Vertically Challenged
Vertically ChallengedVertically Challenged
Vertically Challenged
 

Exceptable - Exception Propagation for PG

  • 2. Exception Propagation, in PostgreSQL and Python Aurynn Shaw, Commandprompt, Inc. PostgreSQL Conference West, 2009 Tuesday, October 20, 2009
  • 3. Background • Large, enterprise Python + Pylons application • Simpycity ORM utilizes significant stored procedures • Strong procedural interfaces Tuesday, October 20, 2009
  • 4. Stored Procedures are Rare • Most people don’t use Stored Procedures. Tuesday, October 20, 2009
  • 5. The Present System Wherein • A Database Query • A Stored Procedure • Or, A Database Query • Exceptions Galore Tuesday, October 20, 2009
  • 6. A Database Query • The App queries the Database Tuesday, October 20, 2009
  • 7. A Database Query • The App queries the Database • Any variety of query Tuesday, October 20, 2009
  • 8. 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
  • 9. A Database Query • The App queries the Database • Any variety of query • Or A Stored Procedure Tuesday, October 20, 2009
  • 10. 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
  • 11. 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
  • 12. Seriously? • This is what we have to work with? Tuesday, October 20, 2009
  • 13. Why this is Important Wherein • Why? • Defining your APIs • Separation of Concerns • Procedural Spaghetti Tuesday, October 20, 2009
  • 14. Why? • Limited information to propagate upwards • Stored Procedures are Harder to use • Permissions violations are difficult to detect Tuesday, October 20, 2009
  • 15. API Undefined • Exceptions are part of your API Tuesday, October 20, 2009
  • 16. API Undefined • Exceptions are part of your API • Easily overlooked Tuesday, October 20, 2009
  • 17. API Undefined • Exceptions are part of your API • Easily overlooked • Delineations will make life easier Tuesday, October 20, 2009
  • 18. Separation of Concerns • The Database is for Database Logic Tuesday, October 20, 2009
  • 19. Separation of Concerns • The Database is for Database Logic • Harder to write Data Logic Tuesday, October 20, 2009
  • 20. Spaghetti Early version of our app didn’t have Exceptable - we were left catching InternalErrors and guessing at what • InternalErrors everywhere the error was, based on timing. Tuesday, October 20, 2009
  • 21. Spaghetti • InternalErrors everywhere • Insufficiency of Information Tuesday, October 20, 2009
  • 22. Spaghetti • InternalErrors everywhere • Insufficiency of Information • Considerable Repeated Code Tuesday, October 20, 2009
  • 23. A Saving Grace • Violating Procedure Signatures -> Python DataError Tuesday, October 20, 2009
  • 24. A Better Deal Wherein • Database API • Easy Python implementation • Universality • Exceptable Tuesday, October 20, 2009
  • 25. Database API • Easier to define an API Tuesday, October 20, 2009
  • 26. Database API • Easier to define an API • The DB becomes part of that API Tuesday, October 20, 2009
  • 27. Database API • Easier to define an API • The DB becomes part of that API • Simple Stored Procedure interface Tuesday, October 20, 2009
  • 28. 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
  • 29. Wonderfully Python • A Simple Decorator Tuesday, October 20, 2009
  • 30. Simply Decorated from exceptable.exceptable import Except base = Except() @base def db_function(): pass Tuesday, October 20, 2009
  • 31. 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
  • 32. Universality • Exceptable Procedures never change • DB logic doesn’t change • Application support is Easy Tuesday, October 20, 2009
  • 33. Exceptable • More Pythonic Database Access • Better exceptions means better app flow Tuesday, October 20, 2009
  • 34. Example Code Wherein • The DB Library • The Application Implementation • Catching Permissions Violations • PostgreSQL 8.4 Tuesday, October 20, 2009
  • 35. 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
  • 36. 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
  • 37. Application Level • Easy to Query the Exception tables Tuesday, October 20, 2009
  • 38. Application Level • Easy to Query the Exception tables • Easy to set up a new library • Python took 50 lines Tuesday, October 20, 2009
  • 39. Our Python Example • The Exceptable decorator is easy to set up • Designed for DB-API integration Tuesday, October 20, 2009
  • 40. In the Application base = Except(InternalError, { 'Exception': Exception, 'NotFoundException': NotFoundError, }) Tuesday, October 20, 2009
  • 41. Our Python Example • The Exceptable decorator is easy to set up • Designed for DB-API integration • User-defined Tuesday, October 20, 2009
  • 42. User Definitions base = Except(InternalError, { 'PermissionError': PermissionError, 'UnknownUser': UnknownUserError, 'NotFoundException': NotFoundError, }) Tuesday, October 20, 2009
  • 43. 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
  • 44. base is a decorator @base def db_api(query): con = db.connect(conn_string) cur = con.cursor() return cur(query) Tuesday, October 20, 2009
  • 45. Which leads to try: rs = db_api(‘select * from test_api()’) except NotFoundError, e: # A hah! A usable error! pass Tuesday, October 20, 2009
  • 46. 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
  • 47. 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
  • 48. Grow, my Pretties! class NotNullError(BaseException): pass class SCE(BaseException): pass base.add({ ‘NotNullException’: NotNullError, ‘SufficientCoffeeException’: SCE }) Tuesday, October 20, 2009
  • 49. Permission Denied • Exceptable.py also wraps the base permission denied • DB permissions violations work at the app level Tuesday, October 20, 2009
  • 50. Vertically Challenged a = c.Function(‘test_auth’); try: result = a() except PermissionDenied, e: abort(403) except NoSuchUser, e: abort(401) Tuesday, October 20, 2009
  • 51. AND THUS Questions? Tuesday, October 20, 2009
  • 52. Get It! https://projects.commandprompt.com/ public/exceptable/ Tuesday, October 20, 2009