Commits

Anonymous committed 51010c9

split out SelectableClassType from TableClassType, so we don't have to do an isinstance check for each dml op

Comments (0)

Files changed (1)

lib/sqlalchemy/ext/sqlsoup.py

 Mapping arbitrary Selectables
 -----------------------------
 
-SqlSoup can map any SQLAlchemy Selectable with the map method.  Let's map a Select object that uses an aggregate function; we'll use the SQLAlchemy Table that SqlSoup introspected as the basis.  (Since we're not mapping to a simple table or join, we need to tell SQLAlchemy how to find the "primary key," which just needs to be unique within the select, and not necessarily correspond to a "real" PK in the database.)
+SqlSoup can map any SQLAlchemy Selectable with the map method. Let's map a
+Select object that uses an aggregate function; we'll use the SQLAlchemy Table
+that SqlSoup introspected as the basis. (Since we're not mapping to a simple
+table or join, we need to tell SQLAlchemy how to find the "primary key," which
+just needs to be unique within the select, and not necessarily correspond to a
+"real" PK in the database.)
 
     >>> from sqlalchemy import select, func
     >>> b = db.books._table
     Traceback (most recent call last):
     ...
     InvalidRequestError: SQLSoup can only modify mapped Tables (found: Alias)
+
+    [tests clear()]
+    >>> db.loans.count()
+    1
+    >>> _ = db.loans.insert(book_id=1, user_name='Bhargan Basepair')
+    >>> db.clear()
+    >>> db.flush()
+    >>> db.loans.count()
+    1
 """
 
 from sqlalchemy import *
 
 # metaclass is necessary to expose class methods with getattr, e.g.
 # we want to pass db.users.select through to users._mapper.select
-def _ddl_check(cls):
-    if not isinstance(cls._table, Table):
-        msg = 'SQLSoup can only modify mapped Tables (found: %s)' \
-              % cls._table.__class__.__name__
-        raise InvalidRequestError(msg)
-class TableClassType(type):
+def _ddl_error(cls):
+    msg = 'SQLSoup can only modify mapped Tables (found: %s)' \
+          % cls._table.__class__.__name__
+    raise InvalidRequestError(msg)
+class SelectableClassType(type):
     def insert(cls, **kwargs):
-        _ddl_check(cls)
-        o = cls()
-        o.__dict__.update(kwargs)
-        return o
+        _ddl_error(cls)
     def delete(cls, *args, **kwargs):
-        _ddl_check(cls)
-        cls._table.delete(*args, **kwargs).execute()
+        _ddl_error(cls)
     def update(cls, whereclause=None, values=None, **kwargs):
-        _ddl_check(cls)
-        cls._table.update(whereclause, values).execute(**kwargs)
+        _ddl_error(cls)
     def _selectable(cls):
         return cls._table
     def __getattr__(cls, attr):
             # called during mapper init
             raise AttributeError()
         return getattr(cls._query, attr)
+class TableClassType(SelectableClassType):
+    def insert(cls, **kwargs):
+        o = cls()
+        o.__dict__.update(kwargs)
+        return o
+    def delete(cls, *args, **kwargs):
+        cls._table.delete(*args, **kwargs).execute()
+    def update(cls, whereclause=None, values=None, **kwargs):
+        cls._table.update(whereclause, values).execute(**kwargs)
             
 
 def _is_outer_join(selectable):
     or selectable._selectable() != selectable:
         raise ArgumentError('class_for_table requires a selectable as its argument')
     mapname = 'Mapped' + _selectable_name(selectable)
-    klass = TableClassType(mapname, (object,), {})
+    if isinstance(selectable, Table):
+        klass = TableClassType(mapname, (object,), {})
+    else:
+        klass = SelectableClassType(mapname, (object,), {})
     def __cmp__(self, o):
         L = self.__class__.c.keys()
         L.sort()
         objectstore.delete(*args, **kwargs)
     def flush(self):
         objectstore.get_session().flush()
-    def rollback(self):
+    def clear(self):
         objectstore.clear()
     def map(self, selectable, **kwargs):
         try: