Proposal: Peewee should provide a standard definition of database errors and wrap the database driver errors in those
Yes, I agree.
 I've added standard exceptions and wrapped the connect / close / execute methods to ensure they raise the "peewee" version where possible:

2d6f43358ebdacb12a6d7319f3fc2c699f22a053

Peewee acts as an ORM and therefore it is not necessary to import the raw/underlying database python library when you create a database. However, if you want to perform tasks that rely on processing underlying errors (such as a databse Integrity Error) you will need to import the underlying database library.

To illustrate a situation where it becomes necessary to import `sqlite3` in order to process integrity violations, I have set out a use case.
#### Existing Behavior (plahouse.py:Loader)

If you wanted to import rows of data and, lets say, one of those rows violated a unique constraint on the table, Peewee will log an error as well as well as raise the _underlying_ exception.

So, just say I wanted to ignore duplicates in my import, I could subclass the `Loader` class and override the `load` method:

``` python
import sqlite3
from playhouse import Loader

class IgnoreDuplicatesLoader(Loader):
    """ A loader that will continue importing even if it sees a duplicate
    value.  Duplicate Values will be skipped.
    """
    def load(self):
        if not self.fields:
            self.analyze_csv()
        if not self.field_names and not self.has_header:
            self.field_names = [
                'field_%d' % i for i in range(len(self.fields))]

        with self.get_reader(self.filename, **self.reader_kwargs) as reader:
            if not self.field_names:
                self.field_names = map(self.clean_field_name, reader.next())
            elif self.has_header:
                reader.next()

            ModelClass = self.get_model_class(self.field_names, self.fields)

            with self.database.transaction():
                ModelClass.create_table(True)
                for row in reader:
                    try:
                        insert = {}
                        for field_name, value in zip(self.field_names, row):
                            if value:
                                insert[field_name] = value.decode('utf-8')
                        if insert:
                            ModelClass.insert(**insert).execute()
                    except sqlite3.IntegrityError, e:
                        print e
                        print "Continuing..."
                        continue

        return ModelClass
```

Note that I had to import `sqlite3` in order to catch that error.  This means that this module code is now tied to an SQLite implementation, and someone cannot change the DB backend without it breaking.  
#### Proposed Operation

Peewee should raise it's own errors which map to the underlying error raised by the database.  So in the above situation, `sqlite3.IntegrityError` would map to `peewee.IntegrityError`
