Index: turbogears/identity/saprovider.py
===================================================================
--- turbogears/identity/saprovider.py	(revision 1535)
+++ turbogears/identity/saprovider.py	(working copy)
@@ -6,14 +6,14 @@
 from turbojson.jsonify import *
 from datetime import *
 from sqlalchemy import *
-from sqlalchemy.ext.activemapper import *
 
 import logging
 log = logging.getLogger("turbogears.identity.saprovider")
 
 from turbogears import identity
 
-__engine__= turbogears.database.PackageEngine( 'turbogears.identity' )
+__engine__ = turbogears.database.PackageEngine( 'turbogears.identity' )
+__meta__ = BoundMetaData(__engine__)
 
 from turbogears.util import load_class
 
@@ -42,11 +42,11 @@
             pass
         # Attempt to load the user. After this code executes, there *WILL* be
         # a _user attribute, even if the value is None.
-        visit= visit_class.get_by( visit_key= self.visit_key )
+        visit= Query(visit_class).get_by( visit_key= self.visit_key )
         if not visit:
             self._user= None
             return None
-        self._user= user_class.get( visit.user_id )
+        self._user= Query(user_class).get( visit.user_id )
         return self._user
     user= property(_get_user)
     
@@ -93,7 +93,7 @@
         if not self.visit_key:
             return
         try:
-            visit= visit_class.get_by(visit_key=self.visit_key)
+            visit= Query(visit_class).get_by(visit_key=self.visit_key)
             objectstore.delete( visit )
             # Clear the current identity
             anon= SqlAlchemyIdentity(None,None)
@@ -137,23 +137,20 @@
 
     def create_provider_model( self ):
         # create the database tables
-        return
-        try:
-            global user_group, group_permission
+        tables = [
+            class_mapper(visit_class).local_table,
+            class_mapper(user_class).local_table,
+            class_mapper(group_class).local_table,
+            class_mapper(permission_class).local_table,
+            class_mapper(user_class).props['groups'].secondary,
+            class_mapper(permission_class).props['groups'].secondary,
+        ]
+        for table in tables:
+            # Perhaps there's a better way to see if a table exists?
+            if table.engine.dialect.has_table(table.engine.session.get_connection(), table.name):
+                continue
+            table.create()
 
-            visit_class.table.create()
-            user_class.table.create()
-            group_class.table.create()
-            permission_class.table.create()
-            user_group.create()
-            group_permission.create()
-            objectstore.commit()
-        except SQLError:
-            return
-        except KeyError:
-            log.warning( "No database is configured: SqlAlchemyIdentityProvider is disabled." )
-            return
-
     def validate_identity( self, user_name, password, visit_key ):
         '''
         Look up the identity represented by user_name and determine whether the
@@ -166,7 +163,7 @@
             groups: a set of group IDs
             permissions: a set of permission IDs
         '''
-        user= user_class.get_by( user_name=user_name )
+        user= Query(user_class).get_by( user_name=user_name )
         if not user:
             log.warning( "No such user: %s", user_name )
             return None
@@ -177,12 +174,11 @@
         log.info( "associating user (%s) with visit (%s)", user.user_name, 
                   visit_key )
         # Link the user to the visit
-        link= visit_class.get_by( visit_key=visit_key )
+        link= Query(visit_class).get_by( visit_key=visit_key )
         if not link:
-            link= visit_class( visit_key=visit_key, user_id=user.user_id )
+            link= visit_class( visit_key=visit_key, user_id=user.id )
         else:
-            link.user_id= user.user_id
-        link.commit()
+            link.user_id= user.id
         return SqlAlchemyIdentity( visit_key, user )
             
     def load_identity( self, visit_key ):
@@ -209,77 +205,77 @@
         return SqlAlchemyIdentity( None )
         
 
-user_group = Table("tg_user_group", __engine__, 
+user_group = Table("tg_user_group", __meta__, 
                       Column("user_id", Integer,
-                              ForeignKey("tg_user.user_id"),
+                              ForeignKey("tg_user.id"),
                               primary_key = True),
                       Column("group_id", Integer,
-                              ForeignKey("tg_group.group_id"),
+                              ForeignKey("tg_group.id"),
                               primary_key = True))
                       
-group_permission = Table("tg_group_permission", __engine__,
+group_permission = Table("tg_group_permission", __meta__,
                             Column("group_id", Integer,
-                                    ForeignKey("tg_group.group_id"),
+                                    ForeignKey("tg_group.id"),
                                     primary_key = True),
                             Column("permission_id", Integer,
-                                ForeignKey("permission.permission_id"),
+                                ForeignKey("tg_permission.id"),
                                     primary_key = True))
 
+visits = Table("tg_visit_identity", __meta__,
+                Column("id", Integer, primary_key=True),
+                Column("visit_key", String(40), nullable=False, unique=True),
+                Column("user_id", Integer, ForeignKey("tg_user.id"), index=True))
 
-class VisitIdentity(ActiveMapper):
-    class mapping:
-        __table__ = "tg_visit_identity"
-        visit_key = column(String, # foreign_key = "visit.visit_key",
-                          primary_key = True)
-        user_id = column(Integer, foreign_key = "tg_user.user_id", index = True)
+groups = Table("tg_group", __meta__,
+                Column("id", Integer, primary_key=True),
+                Column("group_name", Unicode(16), nullable=False, unique=True),
+                Column("display_name", Unicode(255)),
+                Column("created", DateTime, default=datetime.now))
 
+users = Table("tg_user", __meta__,
+                Column("id", Integer, primary_key=True),
+                Column("user_name", Unicode(16), nullable=False, unique=True),
+                Column("email_address", Unicode(255), nullable=False, unique=True),
+                Column("display_name", Unicode(255)),
+                Column("password", Unicode(40)),
+                Column("created", DateTime, default=datetime.now))
 
-class Group(ActiveMapper):
-    """
-    An ultra-simple group definition.
-    """
-    class mapping:
-        __table__ = "tg_group"
-        group_id = column(Integer, primary_key = True)
-        group_name = column(Unicode(16), unique = True)
-        display_name = column(Unicode(255))
-        created = column(DateTime, default = datetime.now)
+permissions = Table("tg_permission", __meta__,
+                Column("id", Integer, primary_key=True),
+                Column("permission_name", Unicode(16), nullable=False, unique=True),
+                Column("description", Unicode(255)))
 
-        #users = many_to_many("User", user_group, backref = "groups")
-        #permissions = many_to_many("Permission", group_permission,
-        #                           backref = "groups")
 
+class VisitIdentity(object):
+    pass
+    
+mapper(VisitIdentity, visits)
 
-class User(ActiveMapper):
-    """
-    Reasonably basic User definition. Probably would want additional attributes.
-    """
-    class mapping:
-        __table__ = "tg_user"
-        user_id = column(Integer, primary_key = True)
-        user_name = column(Unicode(16), unique = True)
-        email_address = column(Unicode(255), unique = True)
-        display_name = column(Unicode(255))
-        password = column(Unicode(40))
-        created = column(DateTime, default = datetime.now)
 
-        groups = many_to_many("Group", user_group, backref = "users")
+class Group(object):
+    pass
+    
+mapper(Group, groups)
 
+
+class User(object):
+
     @property
     def permissions(self):
         perms = set()
         for g in self.groups:
             perms = perms | set(g.permissions)
         return perms
-        
 
-class Permission(ActiveMapper):
-    class mapping:
-        __table__ = "tg_permission"
-        permission_id = column(Integer, primary_key = True)
-        permission_name = column(Unicode(16), unique = True)
-        description = column(Unicode(255))
-        
-        groups = many_to_many("Group", group_permission,
-                              backref = "permissions")
+mapper(User, users, properties = {
+    "groups": relation(Group, secondary=user_group, backref="users")
+})
 
+
+class Permission(object):
+    pass
+
+mapper(Permission, permissions, properties = {
+    "groups": relation(Group, secondary=group_permission, backref="permissions")
+})
+
Index: turbogears/database.py
===================================================================
--- turbogears/database.py	(revision 1535)
+++ turbogears/database.py	(working copy)
@@ -10,9 +10,11 @@
 
 # Provide support for sqlalchemy
 try:
+    import sqlalchemy.mods.threadlocal
     import sqlalchemy
     from sqlalchemy.ext.proxy import AutoConnectEngine
 
+    # Note: this check succeeds with sqlalchemy >0.2 if the threadlocal mod is used
     if not hasattr(sqlalchemy, 'objectstore'):
         sqlalchemy = None # sqlalchemy v.2.1.0 have different API not supported yet
 
@@ -29,6 +31,7 @@
 
             AutoConnectEngine.__init__(self, lookup_dburi, *args, **kwargs)
 
+
 except ImportError:
     sqlalchemy = None
 
@@ -220,18 +223,18 @@
                 sqlalchemy.objectstore.clear()
             retval = func(*args, **kw)
             if sqlalchemy:
-                sqlalchemy.objectstore.commit()
+                sqlalchemy.objectstore.flush()
             commit_all()
             return retval
         except cherrypy.HTTPRedirect:
             commit_all()
             if sqlalchemy:
-                sqlalchemy.objectstore.commit()
+                sqlalchemy.objectstore.flush()
             raise
         except cherrypy.InternalRedirect:
             commit_all()
             if sqlalchemy:
-                sqlalchemy.objectstore.commit()
+                sqlalchemy.objectstore.flush()
             raise
         except:
             # No need to "rollback" the sqlalchemy unit of work, because nothing
@@ -239,6 +242,8 @@
             rollback_all()
             raise
     finally:
+        if sqlalchemy:
+            sqlalchemy.objectstore.close()
         end_all()
 
 def so_to_dict(sqlobj):
Index: turbogears/visit/savisit.py
===================================================================
--- turbogears/visit/savisit.py	(revision 1535)
+++ turbogears/visit/savisit.py	(working copy)
@@ -2,12 +2,12 @@
 from datetime import *
 from turbogears.visit.api import BaseVisitManager, Visit
 from sqlalchemy import *
-from sqlalchemy.ext.activemapper import *
 
 import logging
 log = logging.getLogger("turbogears.identity.savisit")
 
 __engine__= turbogears.database.PackageEngine( 'turbogears.visit' )
+__meta__ = BoundMetaData(__engine__)
 
 
 class SqlAlchemyVisitManager(BaseVisitManager):
@@ -15,15 +15,12 @@
         super(SqlAlchemyVisitManager,self).__init__( timeout )
         
     def create_model(self):
-        try:
+        if not TG_Visit.table.engine.dialect.has_table(
+                TG_Visit.table.engine.session.get_connection(), TG_Visit.table.name):
             TG_Visit.table.create()
-            objectstore.commit()
-        except SQLError:
-            pass
-            
+        
     def new_visit_with_key(self, visit_key):
         visit= TG_Visit( visit_key=visit_key, expiry=datetime.now()+self.timeout )
-        visit.commit()
         return Visit( visit_key, True )
         
     def visit_for_key(self, visit_key):
@@ -48,15 +45,16 @@
                           expiry )
                 table.update( table.c.visit_key==visit_key,
                                   values={'expiry': expiry} ).execute()
-            objectstore.commit()
+            objectstore.flush()
         except:
             objectstore.clear()
             raise
             
 
 tbl__tgvisit = Table('tg_visit', __engine__,
-    Column('visit_key', String(40) , primary_key=True),
-    Column('created', DateTime  , nullable = False ),
+    Column('id', Integer, primary_key=True),
+    Column('visit_key', String(40) , nullable=False, unique=True),
+    Column('created', DateTime ),
     Column('expiry', DateTime ),
 )
 
@@ -65,9 +63,9 @@
     table = tbl__tgvisit
 
     def lookup_visit( cls, visit_key ):
-        return TG_Visit.get( visit_key );
+        return Query(TG_Visit).get_by( visit_key=visit_key );
     lookup_visit= classmethod(lookup_visit)
 
-assign_mapper( TG_Visit , tbl__tgvisit )
+mapper( TG_Visit , tbl__tgvisit )
 
 
Index: turbogears/qstemplates/quickstart/+package+/model.py_tmpl
===================================================================
--- turbogears/qstemplates/quickstart/+package+/model.py_tmpl	(revision 1535)
+++ turbogears/qstemplates/quickstart/+package+/model.py_tmpl	(working copy)
@@ -14,10 +14,10 @@
 #end if
 #if $identity == "sqlalchemy"
 from sqlalchemy import *
-from sqlalchemy.ext.activemapper import *
 
 from turbogears.database import PackageEngine 
 engine = __engine__ = PackageEngine("${package}")
+__meta__ = BoundMetaData(__engine__)
 #end if
 
 #if $identity=="sqlobject"
@@ -107,77 +107,78 @@
 
 #else if $identity=="sqlalchemy"
 # tables for SQLAlchemy identity
-user_group = Table( "user_group", __engine__, 
+user_group = Table( "user_group", __meta__, 
                       Column( "user_id", Integer,
-                              ForeignKey("user.user_id"),
+                              ForeignKey("tg_user.id"),
                               primary_key=True ),
                       Column( "group_id", Integer,
-                              ForeignKey("group.group_id"),
+                              ForeignKey("tg_group.id"),
                               primary_key=True ) )
                       
-group_permission = Table( "group_permission", __engine__,
+group_permission = Table( "group_permission", __meta__,
                             Column( "group_id", Integer,
-                                    ForeignKey("group.group_id"),
+                                    ForeignKey("tg_group.id"),
                                     primary_key=True ),
                             Column( "permission_id", Integer,
-                                ForeignKey("permission.permission_id"),
+                                ForeignKey("permission.id"),
                                     primary_key=True ) )
 
+visits = Table("visit_identity", __meta__,
+                Column("id", Integer, primary_key=True),
+                Column("visit_key", String(40), nullable=False, unique=True),
+                Column("user_id", Integer, ForeignKey("tg_user.id"), index=True))
 
-class VisitIdentity(ActiveMapper):
-    class mapping:
-        __table__="visit_identity"
-        visit_key = column( String, # foreign_key="visit.visit_key",
-                          primary_key=True )
-        user_id = column( Integer, foreign_key="user.user_id", index=True )
+groups = Table("tg_group", __meta__,
+                Column("id", Integer, primary_key=True),
+                Column("group_name", Unicode(16), nullable=False, unique=True),
+                Column("display_name", Unicode(255)),
+                Column("created", DateTime, default=datetime.now))
 
+users = Table("tg_user", __meta__,
+                Column("id", Integer, primary_key=True),
+                Column("user_name", Unicode(16), nullable=False, unique=True),
+                Column("email_address", Unicode(255), nullable=False, unique=True),
+                Column("display_name", Unicode(255)),
+                Column("password", Unicode(40)),
+                Column("created", DateTime, default=datetime.now))
 
-class Group(ActiveMapper):
-    """
-    An ultra-simple group definition.
-    """
-    class mapping:
-        __table__="tg_group"
-        group_id = column( Integer, primary_key=True )
-        group_name = column( Unicode(16), unique=True )
-        display_name = column( Unicode(255) )
-        created = column( DateTime, default=datetime.now )
+permissions = Table("permission", __meta__,
+                Column("id", Integer, primary_key=True),
+                Column("permission_name", Unicode(16), nullable=False, unique=True),
+                Column("description", Unicode(255)))
 
-        users = many_to_many( "User", user_group, backref="groups" )
-        permissions = many_to_many( "Permission", group_permission,
-                                   backref="groups" )
 
+class VisitIdentity(object):
+    pass
+    
+mapper(VisitIdentity, visits)
 
-class User(ActiveMapper):
-    """
-    Reasonably basic User definition. Probably would want additional attributes.
-    """
-    class mapping:
-        __table__="tg_user"
-        user_id = column( Integer, primary_key=True )
-        user_name = column( Unicode(16), unique=True )
-        email_address = column( Unicode(255), unique=True )
-        display_name = column( Unicode(255) )
-        password = column( Unicode(40) )
-        created = column( DateTime, default=datetime.now )
 
-        groups = many_to_many( "Group", user_group, backref="users" )
+class Group(object):
+    pass
+    
+mapper(Group, groups)
 
+
+class User(object):
+
     @property
-    def permissions( self ):
+    def permissions(self):
         perms = set()
         for g in self.groups:
             perms = perms | set(g.permissions)
         return perms
+
+mapper(User, users, properties = {
+    "groups": relation(Group, secondary=user_group, backref="users")
+})
         
 
-class Permission(ActiveMapper):
-    class mapping:
-        __table__="permission"
-        permission_id = column( Integer, primary_key=True )
-        permission_name = column( Unicode(16), unique=True )
-        description = column( Unicode(255) )
-        
-        groups = many_to_many( "Group", group_permission,
-                              backref="permmissions" )
+class Permission(object):
+    pass
+
+mapper(Permission, permissions, properties = {
+    "groups": relation(Group, secondary=group_permission, backref="permissions")
+})
+
 #end if
