The Types System {@name=types}
================

The package `sqlalchemy.types` defines the datatype identifiers which may be used when defining [metadata](rel:table metadata).  This package includes a set of generic types, a set of SQL-specific subclasses of those types, and a small extension system used by specific database connectors to adapt these generic types into database-specific type objects.

### Built-in Types {@name=standard}

SQLAlchemy comes with a set of standard generic datatypes, which are defined as classes.   

The standard set of generic types are:

    {python title="package sqlalchemy.types"}
    class String(TypeEngine):
        def __init__(self, length=None)
        
    class Integer(TypeEngine)
    
    class SmallInteger(Integer)
    
    class Numeric(TypeEngine): 
        def __init__(self, precision=10, length=2)
    
    class Float(Numeric):
        def __init__(self, precision=10)
    
    # DateTime, Date and Time types deal with datetime objects from the Python datetime module
    class DateTime(TypeEngine)
    
    class Date(TypeEngine)
    
    class Time(TypeEngine)
    
    class Binary(TypeEngine): 
        def __init__(self, length=None)
        
    class Boolean(TypeEngine)
    
    # converts unicode strings to raw bytes
    # as bind params, raw bytes to unicode as 
    # rowset values, using the unicode encoding 
    # setting on the engine (defaults to 'utf-8')
    class Unicode(TypeDecorator):
        impl = String
    
    # uses the pickle protocol to serialize data
    # in/out of Binary columns
    class PickleType(TypeDecorator):
        impl = Binary

More specific subclasses of these types are available, which various database engines may choose to implement specifically, allowing finer grained control over types:

    {python}
    class FLOAT(Numeric)
    class TEXT(String)
    class DECIMAL(Numeric)
    class INT(Integer)
    INTEGER = INT
    class TIMESTAMP(DateTime)
    class DATETIME(DateTime)
    class CLOB(String)
    class VARCHAR(String)
    class CHAR(String)
    class BLOB(Binary)
    class BOOLEAN(Boolean)

When using a specific database engine, these types are adapted even further via a set of database-specific subclasses defined by the database engine.
There may eventually be more type objects that are defined for specific databases.  An example of this would be Postgres' Array type.

Type objects are specified to table meta data using either the class itself, or an instance of the class.  Creating an instance of the class allows you to specify parameters for the type, such as string length, numerical precision, etc.:

    {python}
    mytable = Table('mytable', engine, 
        # define type using a class
        Column('my_id', Integer, primary_key=True), 
        
        # define type using an object instance
        Column('value', Number(7,4)) 
    )

### Creating your Own Types {@name=custom}

User-defined types can be created, to support either database-specific types, or customized pre-processing of query parameters as well as post-processing of result set data.  You can make your own classes to perform these operations.  To augment the behavior of a `TypeEngine` type, such as `String`, the `TypeDecorator` class is used:

    {python}
    import sqlalchemy.types as types

    class MyType(types.TypeDecorator):
        """basic type that decorates String, prefixes values with "PREFIX:" on 
        the way in and strips it off on the way out."""
        impl = types.String
        def convert_bind_param(self, value, engine):
            return "PREFIX:" + value
        def convert_result_value(self, value, engine):
            return value[7:]
            
The `Unicode` and `PickleType` classes are instances of `TypeDecorator` already and can be subclassed directly.

To build a type object from scratch, which will not have a corresponding database-specific implementation, subclass `TypeEngine`:

    {python}
    import sqlalchemy.types as types

    class MyType(types.TypeEngine):
        def __init__(self, precision = 8):
            self.precision = precision
        def get_col_spec(self):
            return "MYTYPE(%s)" % self.precision
        def convert_bind_param(self, value, engine):
            return value
        def convert_result_value(self, value, engine):
            return value

