diff --git a/.gitignore b/.gitignore
index 7df8843294..5103ec26e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 vagrant/
 *.pyc
 .idea
+reddwarf_test.sqlite
diff --git a/bin/reddwarf-server b/bin/reddwarf-server
index ac55ee5e94..9f9c04d5fb 100755
--- a/bin/reddwarf-server
+++ b/bin/reddwarf-server
@@ -36,7 +36,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
 from reddwarf import version
 from reddwarf.common import config
 from reddwarf.common import wsgi
-
+from reddwarf.db import db_api
 
 def create_options(parser):
     """Sets up the CLI and config-file options
@@ -60,6 +60,7 @@ if __name__ == '__main__':
     (options, args) = config.parse_options(oparser)
     try:
         conf, app = config.Config.load_paste_app('reddwarf', options, args)
+        db_api.configure_db(conf)
         server = wsgi.Server()
         server.start(app, options.get('port', conf['bind_port']),
             conf['bind_host'])
diff --git a/development/development_enviroment.sh b/development/development_enviroment.sh
index db91ba1b81..7610c1ce35 100644
--- a/development/development_enviroment.sh
+++ b/development/development_enviroment.sh
@@ -33,8 +33,7 @@ curl -d '{"auth":{"passwordCredentials":{"username": "reddwarf", "password": "RE
 #  now get a list of instances, which connects over python-novaclient to nova
 # NOTE THIS AUTH TOKEN NEEDS TO BE CHANGED
 # Also note that keystone uses the tenant id now and _not_ the name
-#curl -H"content-type:application/xml" -H"X-Auth-Project-Id:$REDDWARF_TENANT" -H"X-Auth-User:reddwarf" \
-#     -H'X-Auth-Key:2a2c89c6a7284d32bcb94b4e56f0411c' http://0.0.0.0:8779/v2/$REDDWARF_TENANT/instances
+# curl -H'X-Auth-Token:AUTH_TOKEN' http://0.0.0.0:8779/v0.1/$REDDWARF_TENANT/instances
 
 # Also, you should start up the api node like this
 # bin/reddwarf-api-os-database --flagfile=etc/nova/nova.conf.template
diff --git a/reddwarf/common/exception.py b/reddwarf/common/exception.py
index 42b54ffd89..0908d46bac 100644
--- a/reddwarf/common/exception.py
+++ b/reddwarf/common/exception.py
@@ -33,9 +33,9 @@ class ReddwarfError(openstack_exception.OpenstackException):
         super(ReddwarfError, self).__init__(**kwargs)
 
 
-class ThisIsATestError(ReddwarfError):
+class DBConstraintError(ReddwarfError):
 
-    message = _("Data Missing")
+    message = _("Failed to save %(model_name)s because: %(error)s")
 
 
 
diff --git a/reddwarf/common/utils.py b/reddwarf/common/utils.py
index 9c11fde4be..75348a2c34 100644
--- a/reddwarf/common/utils.py
+++ b/reddwarf/common/utils.py
@@ -16,12 +16,33 @@
 #    under the License.
 """I totally stole most of this from melange, thx guys!!!"""
 
+import datetime
+import inspect
+import re
+import uuid
+
+from reddwarf.openstack.common import utils as openstack_utils
+
+
+import_class = openstack_utils.import_class
+import_object = openstack_utils.import_object
+bool_from_string = openstack_utils.bool_from_string
+
+
 def stringify_keys(dictionary):
     if dictionary is None:
         return None
     return dict((str(key), value) for key, value in dictionary.iteritems())
 
 
+def generate_uuid():
+    return str(uuid.uuid4())
+
+
+def utcnow():
+    return datetime.datetime.utcnow()
+
+
 class cached_property(object):
     """A decorator that converts a function into a lazy property.
 
@@ -50,3 +71,42 @@ class cached_property(object):
         value = self.func(obj)
         setattr(obj, self.__name__, value)
         return value
+
+class MethodInspector(object):
+
+    def __init__(self, func):
+        self._func = func
+
+    @cached_property
+    def required_args(self):
+        return self.args[0:self.required_args_count]
+
+    @cached_property
+    def optional_args(self):
+        keys = self.args[self.required_args_count: len(self.args)]
+        return zip(keys, self.defaults)
+
+    @cached_property
+    def defaults(self):
+        return self.argspec.defaults or ()
+
+    @cached_property
+    def required_args_count(self):
+        return len(self.args) - len(self.defaults)
+
+    @cached_property
+    def args(self):
+        args = self.argspec.args
+        if inspect.ismethod(self._func):
+            args.pop(0)
+        return args
+
+    @cached_property
+    def argspec(self):
+        return inspect.getargspec(self._func)
+
+    def __str__(self):
+        optionals = ["[{0}=<{0}>]".format(k) for k, v in self.optional_args]
+        required = ["{0}=<{0}>".format(arg) for arg in self.required_args]
+        args_str = ' '.join(required + optionals)
+        return "%s %s" % (self._func.__name__, args_str)
diff --git a/reddwarf/database/models.py b/reddwarf/database/models.py
index a352d9dfc8..b685bfd45f 100644
--- a/reddwarf/database/models.py
+++ b/reddwarf/database/models.py
@@ -19,7 +19,12 @@
 
 import logging
 import netaddr
+
+from reddwarf import db
+
 from reddwarf.common import config
+from reddwarf.common import exception
+from reddwarf.common import utils
 from novaclient.v1_1.client import Client
 
 LOG = logging.getLogger('reddwarf.database.models')
@@ -41,6 +46,30 @@ class ModelBase(object):
         data_fields = self._data_fields + self._auto_generated_attrs
         return dict([(field, self[field]) for field in data_fields])
 
+    def is_valid(self):
+        self.errors = {}
+#        self._validate_columns_type()
+#        self._before_validate()
+#        self._validate()
+        return self.errors == {}
+
+    def __setitem__(self, key, value):
+        setattr(self, key, value)
+
+    def __getitem__(self, key):
+        return getattr(self, key)
+
+    def __eq__(self, other):
+        if not hasattr(other, 'id'):
+            return False
+        return type(other) == type(self) and other.id == self.id
+
+    def __ne__(self, other):
+        return not self == other
+
+    def __hash__(self):
+        return self.id.__hash__()
+
 
 class RemoteModelBase(ModelBase):
 
@@ -89,4 +118,49 @@ class Instances(Instance):
 
 
 class DatabaseModelBase(ModelBase):
-    _auto_generated_attrs = ["id", "created_at", "updated_at"]
\ No newline at end of file
+    _auto_generated_attrs = ['id']
+
+    @classmethod
+    def create(cls, **values):
+        values['id'] = utils.generate_uuid()
+        print values
+#        values['created_at'] = utils.utcnow()
+        instance = cls(**values).save()
+#        instance._notify_fields("create")
+        return instance
+
+    def save(self):
+        if not self.is_valid():
+            raise InvalidModelError(self.errors)
+#        self._convert_columns_to_proper_type()
+#        self._before_save()
+        self['updated_at'] = utils.utcnow()
+        LOG.debug("Saving %s: %s" % (self.__class__.__name__, self.__dict__))
+        return db.db_api.save(self)
+
+    def __init__(self, **kwargs):
+        self.merge_attributes(kwargs)
+
+    def merge_attributes(self, values):
+        """dict.update() behaviour."""
+        for k, v in values.iteritems():
+            self[k] = v
+
+
+
+class DBInstance(DatabaseModelBase):
+    _data_fields = ['name', 'status']
+
+def persisted_models():
+    return {
+        'instance': DBInstance,
+        }
+
+class InvalidModelError(exception.ReddwarfError):
+
+    message = _("The following values are invalid: %(errors)s")
+
+    def __init__(self, errors, message=None):
+        super(InvalidModelError, self).__init__(message, errors=errors)
+
+
diff --git a/reddwarf/database/service.py b/reddwarf/database/service.py
index 22c5fd5f96..b87d4e6c3c 100644
--- a/reddwarf/database/service.py
+++ b/reddwarf/database/service.py
@@ -50,6 +50,8 @@ class InstanceController(BaseController):
     def index(self, req, tenant_id):
         """Return all instances."""
         servers = models.Instances(req.headers["X-Auth-Token"]).data()
+        # Test to check that the db code works. this will eventually be removed
+        models.DBInstance.create(name='foo', status='status_foo')
         return wsgi.Result(views.InstancesView(servers).data(), 201)
 
     def show(self, req, tenant_id, id):
diff --git a/reddwarf/db/__init__.py b/reddwarf/db/__init__.py
index d65c689a83..623910d763 100644
--- a/reddwarf/db/__init__.py
+++ b/reddwarf/db/__init__.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 
-# Copyright 2011 OpenStack LLC.
+# Copyright 2010-2011 OpenStack LLC.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -14,3 +14,86 @@
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
+
+import optparse
+
+from reddwarf.common import utils
+from reddwarf.common import config
+
+
+db_api = utils.import_object(config.Config.get("db_api_implementation",
+    "reddwarf.db.sqlalchemy.api"))
+
+
+class Query(object):
+    """Mimics sqlalchemy query object.
+
+    This class allows us to store query conditions and use them with
+    bulk updates and deletes just like sqlalchemy query object.
+    Using this class makes the models independent of sqlalchemy
+
+    """
+    def __init__(self, model, query_func, **conditions):
+        self._query_func = query_func
+        self._model = model
+        self._conditions = conditions
+
+    def all(self):
+        return db_api.list(self._query_func, self._model, **self._conditions)
+
+    def count(self):
+        return db_api.count(self._query_func, self._model, **self._conditions)
+
+    def __iter__(self):
+        return iter(self.all())
+
+    def update(self, **values):
+        db_api.update_all(self._query_func, self._model, self._conditions,
+            values)
+
+    def delete(self):
+        db_api.delete_all(self._query_func, self._model, **self._conditions)
+
+    def limit(self, limit=200, marker=None, marker_column=None):
+        return db_api.find_all_by_limit(self._query_func,
+            self._model,
+            self._conditions,
+            limit=limit,
+            marker=marker,
+            marker_column=marker_column)
+
+    def paginated_collection(self, limit=200, marker=None, marker_column=None):
+        collection = self.limit(int(limit) + 1, marker, marker_column)
+        if len(collection) > int(limit):
+            return (collection[0:-1], collection[-2]['id'])
+        return (collection, None)
+
+
+class Queryable(object):
+
+    def __getattr__(self, item):
+        return lambda model, **conditions: Query(
+            model, query_func=getattr(db_api, item), **conditions)
+
+db_query = Queryable()
+
+
+def add_options(parser):
+    """Adds any configuration options that the db layer might have.
+
+    :param parser: An optparse.OptionParser object
+    :retval None
+
+    """
+    help_text = ("The following configuration options are specific to the "
+                 "Reddwarf database.")
+
+    group = optparse.OptionGroup(parser,
+        "Registry Database Options",
+        help_text)
+    group.add_option('--sql-connection',
+        metavar="CONNECTION",
+        default=None,
+        help="A valid SQLAlchemy connection string for the "
+             "registry database. Default: %default")
+    parser.add_option_group(group)
diff --git a/reddwarf/db/sqlalchemy/__init__.py b/reddwarf/db/sqlalchemy/__init__.py
new file mode 100644
index 0000000000..b60695702c
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/__init__.py
@@ -0,0 +1,16 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010-2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
diff --git a/reddwarf/db/sqlalchemy/api.py b/reddwarf/db/sqlalchemy/api.py
new file mode 100644
index 0000000000..393a3614ec
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/api.py
@@ -0,0 +1,144 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import sqlalchemy.exc
+from sqlalchemy import and_
+from sqlalchemy import or_
+from sqlalchemy.orm import aliased
+
+from reddwarf.common import exception
+from reddwarf.common import utils
+from reddwarf.db.sqlalchemy import migration
+from reddwarf.db.sqlalchemy import mappers
+from reddwarf.db.sqlalchemy import session
+
+
+def list(query_func, *args, **kwargs):
+    return query_func(*args, **kwargs).all()
+
+
+def count(query, *args, **kwargs):
+    return query(*args, **kwargs).count()
+
+
+def find_all(model, **conditions):
+    return _query_by(model, **conditions)
+
+
+def find_all_by_limit(query_func, model, conditions, limit, marker=None,
+                      marker_column=None):
+    return _limits(query_func, model, conditions, limit, marker,
+                   marker_column).all()
+
+
+def find_by(model, **kwargs):
+    return _query_by(model, **kwargs).first()
+
+
+def save(model):
+    try:
+        db_session = session.get_session()
+        model = db_session.merge(model)
+        db_session.flush()
+        return model
+    except sqlalchemy.exc.IntegrityError as error:
+        raise exception.DBConstraintError(model_name=model.__class__.__name__,
+                                          error=str(error.orig))
+
+
+def delete(model):
+    db_session = session.get_session()
+    model = db_session.merge(model)
+    db_session.delete(model)
+    db_session.flush()
+
+
+def delete_all(query_func, model, **conditions):
+    query_func(model, **conditions).delete()
+
+
+def update(model, **values):
+    for k, v in values.iteritems():
+        model[k] = v
+
+
+def update_all(query_func, model, conditions, values):
+    query_func(model, **conditions).update(values)
+
+
+def configure_db(options, *plugins):
+    session.configure_db(options)
+    configure_db_for_plugins(options, *plugins)
+
+
+def configure_db_for_plugins(options, *plugins):
+    for plugin in plugins:
+        session.configure_db(options, models_mapper=plugin.mapper)
+
+
+def drop_db(options):
+    session.drop_db(options)
+
+
+def clean_db():
+    session.clean_db()
+
+
+def db_sync(options, version=None, repo_path=None):
+    migration.db_sync(options, version, repo_path)
+
+
+def db_upgrade(options, version=None, repo_path=None):
+    migration.upgrade(options, version, repo_path)
+
+
+def db_downgrade(options, version, repo_path=None):
+    migration.downgrade(options, version, repo_path)
+
+
+def db_reset(options, *plugins):
+    drop_db(options)
+    db_sync(options)
+    db_reset_for_plugins(options, *plugins)
+    configure_db(options)
+
+
+def db_reset_for_plugins(options, *plugins):
+    for plugin in plugins:
+        repo_path = plugin.migrate_repo_path()
+        if repo_path:
+            db_sync(options, repo_path=repo_path)
+    configure_db(options, *plugins)
+
+
+def _base_query(cls):
+    return session.get_session().query(cls)
+
+
+def _query_by(cls, **conditions):
+    query = _base_query(cls)
+    if conditions:
+        query = query.filter_by(**conditions)
+    return query
+
+
+def _limits(query_func, model, conditions, limit, marker, marker_column=None):
+    query = query_func(model, **conditions)
+    marker_column = marker_column or model.id
+    if marker:
+        query = query.filter(marker_column > marker)
+    return query.order_by(marker_column).limit(limit)
diff --git a/reddwarf/db/sqlalchemy/mappers.py b/reddwarf/db/sqlalchemy/mappers.py
new file mode 100644
index 0000000000..c916b1fd19
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/mappers.py
@@ -0,0 +1,37 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from sqlalchemy import MetaData
+from sqlalchemy import Table
+from sqlalchemy import orm
+from sqlalchemy.orm import exc as orm_exc
+
+
+def map(engine, models):
+    meta = MetaData()
+    meta.bind = engine
+    if mapping_exists(models['instance']):
+        return
+
+    orm.mapper(models['instance'], Table('instances', meta, autoload=True))
+
+def mapping_exists(model):
+    try:
+        orm.class_mapper(model)
+        return True
+    except orm_exc.UnmappedClassError:
+        return False
diff --git a/reddwarf/db/sqlalchemy/migrate_repo/README b/reddwarf/db/sqlalchemy/migrate_repo/README
new file mode 100644
index 0000000000..6218f8cac4
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/migrate_repo/README
@@ -0,0 +1,4 @@
+This is a database migration repository.
+
+More information at
+http://code.google.com/p/sqlalchemy-migrate/
diff --git a/reddwarf/db/sqlalchemy/migrate_repo/__init__.py b/reddwarf/db/sqlalchemy/migrate_repo/__init__.py
new file mode 100644
index 0000000000..d65c689a83
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/migrate_repo/__init__.py
@@ -0,0 +1,16 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
diff --git a/reddwarf/db/sqlalchemy/migrate_repo/manage.py b/reddwarf/db/sqlalchemy/migrate_repo/manage.py
new file mode 100644
index 0000000000..84bf4d6cb9
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/migrate_repo/manage.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from migrate.versioning.shell import main
+
+main(debug='False', repository='.')
diff --git a/reddwarf/db/sqlalchemy/migrate_repo/migrate.cfg b/reddwarf/db/sqlalchemy/migrate_repo/migrate.cfg
new file mode 100644
index 0000000000..3089120144
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/migrate_repo/migrate.cfg
@@ -0,0 +1,21 @@
+[db_settings]
+# Used to identify which repository this database is versioned under.
+# You can use the name of your project.
+repository_id=Reddwarf Migrations
+
+# The name of the database table used to track the schema version.
+# This name shouldn't already be used by your project.
+# If this is changed once a database is under version control, you'll need to
+# change the table name in each database too.
+version_table=migrate_version
+
+# When committing a change script, Migrate will attempt to generate the
+# sql for all supported databases; normally, if one of them fails - probably
+# because you don't have that database installed - it is ignored and the
+# commit continues, perhaps ending successfully.
+# Databases in this list MUST compile successfully during a commit, or the
+# entire commit will fail. List the databases your application will actually
+# be using to ensure your updates to that database work properly.
+# This must be a list; example: ['postgres','sqlite']
+
+required_dbs=['mysql','postgres','sqlite']
diff --git a/reddwarf/db/sqlalchemy/migrate_repo/schema.py b/reddwarf/db/sqlalchemy/migrate_repo/schema.py
new file mode 100644
index 0000000000..6970dac698
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/migrate_repo/schema.py
@@ -0,0 +1,63 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+"""Various conveniences used for migration scripts."""
+
+import logging
+import sqlalchemy.types
+
+
+logger = logging.getLogger('reddwarf.db.sqlalchemy.migrate_repo.schema')
+
+
+String = lambda length: sqlalchemy.types.String(
+    length=length, convert_unicode=False, assert_unicode=None,
+    unicode_error=None, _warn_on_bytestring=False)
+
+
+Text = lambda: sqlalchemy.types.Text(
+    length=None, convert_unicode=False, assert_unicode=None,
+    unicode_error=None, _warn_on_bytestring=False)
+
+
+Boolean = lambda: sqlalchemy.types.Boolean(create_constraint=True, name=None)
+
+
+DateTime = lambda: sqlalchemy.types.DateTime(timezone=False)
+
+
+Integer = lambda: sqlalchemy.types.Integer()
+
+
+BigInteger = lambda: sqlalchemy.types.BigInteger()
+
+
+def create_tables(tables):
+    for table in tables:
+        logger.info("creating table %(table)s" % locals())
+        table.create()
+
+
+def drop_tables(tables):
+    for table in tables:
+        logger.info("dropping table %(table)s" % locals())
+        table.drop()
+
+
+def Table(name, metadata, *args, **kwargs):
+    return sqlalchemy.schema.Table(name, metadata, *args,
+                                   mysql_engine='INNODB', **kwargs)
diff --git a/reddwarf/db/sqlalchemy/migrate_repo/versions/001_base_schema.py b/reddwarf/db/sqlalchemy/migrate_repo/versions/001_base_schema.py
new file mode 100644
index 0000000000..018f50febf
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/migrate_repo/versions/001_base_schema.py
@@ -0,0 +1,48 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from sqlalchemy import ForeignKey
+from sqlalchemy.schema import Column
+from sqlalchemy.schema import MetaData
+from sqlalchemy.schema import UniqueConstraint
+
+from reddwarf.db.sqlalchemy.migrate_repo.schema import Boolean
+from reddwarf.db.sqlalchemy.migrate_repo.schema import create_tables
+from reddwarf.db.sqlalchemy.migrate_repo.schema import DateTime
+from reddwarf.db.sqlalchemy.migrate_repo.schema import drop_tables
+from reddwarf.db.sqlalchemy.migrate_repo.schema import Integer
+from reddwarf.db.sqlalchemy.migrate_repo.schema import BigInteger
+from reddwarf.db.sqlalchemy.migrate_repo.schema import String
+from reddwarf.db.sqlalchemy.migrate_repo.schema import Table
+
+
+meta = MetaData()
+
+instances = Table('instances', meta,
+        Column('id', String(36), primary_key=True, nullable=False),
+        Column('name', String(255)),
+        Column('status', String(255)))
+
+
+def upgrade(migrate_engine):
+    meta.bind = migrate_engine
+    create_tables([instances,])
+
+
+def downgrade(migrate_engine):
+    meta.bind = migrate_engine
+    drop_tables([instances,])
diff --git a/reddwarf/db/sqlalchemy/migrate_repo/versions/__init__.py b/reddwarf/db/sqlalchemy/migrate_repo/versions/__init__.py
new file mode 100644
index 0000000000..e5e8b3743b
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/migrate_repo/versions/__init__.py
@@ -0,0 +1,18 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+# template repository default versions module
diff --git a/reddwarf/db/sqlalchemy/migration.py b/reddwarf/db/sqlalchemy/migration.py
new file mode 100644
index 0000000000..ca0ecdc8d4
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/migration.py
@@ -0,0 +1,134 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import logging
+import os
+
+from migrate.versioning import api as versioning_api
+# See LP bug #719834. sqlalchemy-migrate changed location of
+# exceptions.py after 0.6.0.
+try:
+    from migrate.versioning import exceptions as versioning_exceptions
+except ImportError:
+    from migrate import exceptions as versioning_exceptions
+
+from reddwarf.common import exception
+
+
+logger = logging.getLogger('reddwarf.db.sqlalchemy.migration')
+
+
+def db_version(options, repo_path=None):
+    """Return the database's current migration number.
+
+    :param options: options dict
+    :retval version number
+
+    """
+    repo_path = get_migrate_repo_path(repo_path)
+    sql_connection = options['sql_connection']
+    try:
+        return versioning_api.db_version(sql_connection, repo_path)
+    except versioning_exceptions.DatabaseNotControlledError:
+        msg = ("database '%(sql_connection)s' is not under migration control"
+               % locals())
+        raise exception.DatabaseMigrationError(msg)
+
+
+def upgrade(options, version=None, repo_path=None):
+    """Upgrade the database's current migration level.
+
+    :param options: options dict
+    :param version: version to upgrade (defaults to latest)
+    :retval version number
+
+    """
+    db_version(options, repo_path)  # Ensure db is under migration control
+    repo_path = get_migrate_repo_path(repo_path)
+    sql_connection = options['sql_connection']
+    version_str = version or 'latest'
+    logger.info("Upgrading %(sql_connection)s to version %(version_str)s" %
+                locals())
+    return versioning_api.upgrade(sql_connection, repo_path, version)
+
+
+def downgrade(options, version, repo_path=None):
+    """Downgrade the database's current migration level.
+
+    :param options: options dict
+    :param version: version to downgrade to
+    :retval version number
+
+    """
+    db_version(options, repo_path)  # Ensure db is under migration control
+    repo_path = get_migrate_repo_path(repo_path)
+    sql_connection = options['sql_connection']
+    logger.info("Downgrading %(sql_connection)s to version %(version)s" %
+                locals())
+    return versioning_api.downgrade(sql_connection, repo_path, version)
+
+
+def version_control(options, repo_path=None):
+    """Place a database under migration control.
+
+    :param options: options dict
+
+    """
+    sql_connection = options['sql_connection']
+    try:
+        _version_control(options)
+    except versioning_exceptions.DatabaseAlreadyControlledError:
+        msg = ("database '%(sql_connection)s' is already under migration "
+               "control" % locals())
+        raise exception.DatabaseMigrationError(msg)
+
+
+def _version_control(options, repo_path):
+    """Place a database under migration control.
+
+    :param options: options dict
+
+    """
+    repo_path = get_migrate_repo_path(repo_path)
+    sql_connection = options['sql_connection']
+    return versioning_api.version_control(sql_connection, repo_path)
+
+
+def db_sync(options, version=None, repo_path=None):
+    """Place a database under migration control and perform an upgrade.
+
+    :param options: options dict
+    :param repo_path: used for plugin db migrations, defaults to main repo
+    :retval version number
+
+    """
+    try:
+        _version_control(options, repo_path)
+    except versioning_exceptions.DatabaseAlreadyControlledError:
+        pass
+
+    upgrade(options, version=version, repo_path=repo_path)
+
+
+def get_migrate_repo_path(repo_path=None):
+    """Get the path for the migrate repository."""
+
+    default_path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
+                        'migrate_repo')
+    repo_path = repo_path or default_path
+    assert os.path.exists(repo_path)
+    return repo_path
diff --git a/reddwarf/db/sqlalchemy/session.py b/reddwarf/db/sqlalchemy/session.py
new file mode 100644
index 0000000000..17c3641f1e
--- /dev/null
+++ b/reddwarf/db/sqlalchemy/session.py
@@ -0,0 +1,104 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import contextlib
+import logging
+from sqlalchemy import create_engine
+from sqlalchemy import MetaData
+from sqlalchemy.orm import sessionmaker
+
+from reddwarf import database
+from reddwarf.common import config
+from reddwarf.db.sqlalchemy import mappers
+
+_ENGINE = None
+_MAKER = None
+
+
+LOG = logging.getLogger('reddwarf.db.sqlalchemy.session')
+
+
+def configure_db(options, models_mapper=None):
+    configure_sqlalchemy_log(options)
+    global _ENGINE
+    if not _ENGINE:
+        _ENGINE = _create_engine(options)
+    if models_mapper:
+        models_mapper.map(_ENGINE)
+    else:
+        mappers.map(_ENGINE, database.models.persisted_models())
+
+
+def configure_sqlalchemy_log(options):
+    debug = config.get_option(options, 'debug', type='bool', default=False)
+    verbose = config.get_option(options, 'verbose', type='bool', default=False)
+    logger = logging.getLogger('sqlalchemy.engine')
+    if debug:
+        logger.setLevel(logging.DEBUG)
+    elif verbose:
+        logger.setLevel(logging.INFO)
+
+
+def _create_engine(options):
+    engine_args = {
+        "pool_recycle": config.get_option(options,
+                                          'sql_idle_timeout',
+                                          type='int',
+                                          default=3600),
+        "echo": config.get_option(options,
+                                  'sql_query_log',
+                                  type='bool',
+                                  default=False),
+    }
+    LOG.info("Creating SQLAlchemy engine with args: %s" % engine_args)
+    return create_engine(options['sql_connection'], **engine_args)
+
+
+def get_session(autocommit=True, expire_on_commit=False):
+    """Helper method to grab session."""
+
+    global _MAKER, _ENGINE
+    if not _MAKER:
+        assert _ENGINE
+        _MAKER = sessionmaker(bind=_ENGINE,
+                              autocommit=autocommit,
+                              expire_on_commit=expire_on_commit)
+    return _MAKER()
+
+
+def raw_query(model, autocommit=True, expire_on_commit=False):
+    return get_session(autocommit, expire_on_commit).query(model)
+
+
+def clean_db():
+    global _ENGINE
+    meta = MetaData()
+    meta.reflect(bind=_ENGINE)
+    with contextlib.closing(_ENGINE.connect()) as con:
+        trans = con.begin()
+        for table in reversed(meta.sorted_tables):
+            if table.name != "migrate_version":
+                con.execute(table.delete())
+        trans.commit()
+
+
+def drop_db(options):
+    meta = MetaData()
+    engine = _create_engine(options)
+    meta.bind = engine
+    meta.reflect()
+    meta.drop_all()