]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
exception package added, support throughout
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 19 Feb 2006 00:19:16 +0000 (00:19 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 19 Feb 2006 00:19:16 +0000 (00:19 +0000)
16 files changed:
lib/sqlalchemy/__init__.py
lib/sqlalchemy/ansisql.py
lib/sqlalchemy/attributes.py
lib/sqlalchemy/engine.py
lib/sqlalchemy/exceptions.py [new file with mode: 0644]
lib/sqlalchemy/mapping/__init__.py
lib/sqlalchemy/mapping/mapper.py
lib/sqlalchemy/mapping/objectstore.py
lib/sqlalchemy/mapping/properties.py
lib/sqlalchemy/mapping/topological.py
lib/sqlalchemy/schema.py
lib/sqlalchemy/sql.py
lib/sqlalchemy/util.py
test/cycles.py
test/mapper.py
test/objectstore.py

index 29b2dfd608ec6fe53aa19300f08dca2d8704d787..0c8aa2fe018ba92e5054ff08d51927a045b42f1c 100644 (file)
@@ -7,6 +7,7 @@
 from engine import *
 from types import *
 from schema import *
+from exceptions import *
 from sql import *
 import mapping as mapperlib
 from mapping import *
index a9c6bb2071761ee3afae36d0acc25318c40902ec..88bd0f8bd1a01bb2fd8a4c3140f44a369f540207 100644 (file)
@@ -145,8 +145,6 @@ class ANSICompiler(sql.Compiled):
     def visit_label(self, label):
         if len(self.select_stack):
             self.typemap.setdefault(label.name.lower(), label.obj.type)
-            if label.obj.type is None:
-                raise "nonetype" + repr(label.obj)
         self.strings[label] = self.strings[label.obj] + " AS "  + label.name
         
     def visit_column(self, column):
index f6abe6b31db2f775dc81f4864eb2953d664a94ec..7a9f13c57cdf9c2557db72417681c1043c74975f 100644 (file)
@@ -76,7 +76,7 @@ class PropHistory(object):
         return self.obj.__dict__[self.key]
     def setattr(self, value):
         if isinstance(value, list):
-            raise ("assigning a list to scalar property '%s' on '%s' instance %d" % (self.key, self.obj.__class__.__name__, id(self.obj)))
+            raise InvalidRequestError("assigning a list to scalar property '%s' on '%s' instance %d" % (self.key, self.obj.__class__.__name__, id(self.obj)))
         orig = self.obj.__dict__.get(self.key, None)
         if orig is value:
             return
index d553eee2db2e7f728958532899911da70bf59a33..1ca9d00fda19391443873ab9a504ca3e3289ae58 100644 (file)
@@ -23,13 +23,13 @@ The term "database-specific" will be used to describe any object or function tha
 corresponding to a particular vendor, such as mysql-specific, sqlite-specific, etc.
 """
 
-import sqlalchemy.schema as schema
 import sqlalchemy.pool
-import sqlalchemy.util as util
-import sqlalchemy.sql as sql
-import StringIO, sys, re
+import schema
+import exceptions
+import util
+import sql
 import sqlalchemy.types as types
-import sqlalchemy.databases
+import StringIO, sys, re
 
 __all__ = ['create_engine', 'engine_descriptors']
 
@@ -236,7 +236,7 @@ class SQLEngine(schema.SchemaEngine):
             self.bindtemplate = "%%(%s)s"
             self.positional = True
         else:
-            raise "Unsupported paramstyle '%s'" % self._paramstyle
+            raise DBAPIError("Unsupported paramstyle '%s'" % self._paramstyle)
         
     def type_descriptor(self, typeobj):
         """provides a database-specific TypeEngine object, given the generic object
@@ -609,10 +609,10 @@ class SQLEngine(schema.SchemaEngine):
         return ResultProxy(cursor, self, typemap=typemap)
 
     def _execute(self, c, statement, parameters):
-        #try:
-        c.execute(statement, parameters)
-        #except:
-        #    raise "OK ERROR " + statement + " " + repr(parameters)
+        try:
+            c.execute(statement, parameters)
+        except Exception, e:
+            raise exceptions.SQLError(statement, parameters, e)
         self.context.rowcount = c.rowcount
     def _executemany(self, c, statement, parameters):
         c.executemany(statement, parameters)
@@ -642,7 +642,7 @@ class ResultProxy:
         def __init__(self, key):
             self.key = key
         def convert_result_value(self, arg, engine):
-            raise "Ambiguous column name '%s' in result set! try 'use_labels' option on select statement." % (self.key)
+            raise InvalidRequestError("Ambiguous column name '%s' in result set! try 'use_labels' option on select statement." % (self.key))
     
     def __init__(self, cursor, engine, typemap = None):
         """ResultProxy objects are constructed via the execute() method on SQLEngine."""
@@ -663,7 +663,7 @@ class ResultProxy:
                 else:
                     rec = (types.NULLTYPE, i)
                 if rec[0] is None:
-                    raise "None for metadata " + colname
+                    raise DBAPIError("None for metadata " + colname)
                 if self.props.setdefault(colname, rec) is not rec:
                     self.props[colname] = (ResultProxy.AmbiguousColumn(colname), 0)
                 self.keys.append(colname)
diff --git a/lib/sqlalchemy/exceptions.py b/lib/sqlalchemy/exceptions.py
new file mode 100644 (file)
index 0000000..6883293
--- /dev/null
@@ -0,0 +1,41 @@
+# exceptions.py - exceptions for SQLAlchemy
+# Copyright (C) 2005,2006 Michael Bayer mike_mp@zzzcomputing.com
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+
+class SQLAlchemyError(Exception):
+    """generic error class"""
+    pass
+    
+class SQLError(SQLAlchemyError):
+    """raised when the execution of a SQL statement fails.  includes accessors
+    for the underlying exception, as well as the SQL and bind parameters"""
+    def __init__(self, statement, params, orig):
+        SQLAlchemyError.__init__(self, "(%s) %s"% (orig.__class__.__name__, str(orig)))
+        self.statement = statement
+        self.params = params
+        self.orig = orig
+
+class ArgumentError(SQLAlchemyError):
+    """raised for all those conditions where invalid arguments are sent to constructed
+    objects.  This error generally corresponds to construction time state errors."""
+    pass
+    
+class CommitError(SQLAlchemyError):
+    """raised when an invalid condition is detected upon a commit()"""
+    pass
+    
+class InvalidRequestError(SQLAlchemyError):
+    """sqlalchemy was asked to do something it cant do, return nonexistent data, etc.
+    This error generally corresponds to runtime state errors."""
+    pass
+
+class AssertionError(SQLAlchemyError):
+    """corresponds to internal state being detected in an invalid state"""
+    pass
+    
+class DBAPIError(SQLAlchemyError):
+    """something weird happened with a particular DBAPI version"""
+    pass
\ No newline at end of file
index 538559e43c4bcf179616b1e219867465e892461a..64258fa6546a758400ea1569160260e830ca2c30 100644 (file)
@@ -13,6 +13,7 @@ import sqlalchemy.schema as schema
 import sqlalchemy.engine as engine
 import sqlalchemy.util as util
 import objectstore
+from exceptions import *
 import types as types
 from mapper import *
 from properties import *
@@ -27,7 +28,7 @@ def relation(*args, **kwargs):
     """provides a relationship of a primary Mapper to a secondary Mapper, which corresponds
     to a parent-child or associative table relationship."""
     if len(args) > 1 and isinstance(args[0], type):
-        raise ValueError("relation(class, table, **kwargs) is deprecated.  Please use relation(class, **kwargs) or relation(mapper, **kwargs).")
+        raise ArgumentError("relation(class, table, **kwargs) is deprecated.  Please use relation(class, **kwargs) or relation(mapper, **kwargs).")
     return _relation_loader(*args, **kwargs)
 
 def _relation_loader(mapper, secondary=None, primaryjoin=None, secondaryjoin=None, lazy=True, **kwargs):
@@ -101,7 +102,7 @@ def class_mapper(class_):
         pass
     except AttributeError:
         pass
-    raise "Class '%s' has no mapper associated with it" % class_.__name__
+    raise InvalidRequestError("Class '%s' has no mapper associated with it" % class_.__name__)
 
 
 def assign_mapper(class_, *args, **params):
index 24bf11fd8f343ce63fae4c1bfbcecc8cc1a5ab06..5fed7c7f2955879002fed677ed6a2f6ec343c3bf 100644 (file)
@@ -9,6 +9,7 @@ import sqlalchemy.sql as sql
 import sqlalchemy.schema as schema
 import sqlalchemy.engine as engine
 import sqlalchemy.util as util
+from sqlalchemy.exceptions import *
 import objectstore
 import sys
 import weakref
@@ -47,7 +48,7 @@ class Mapper(object):
         self._options = {}
         
         if not issubclass(class_, object):
-            raise TypeError("Class '%s' is not a new-style class" % class_.__name__)
+            raise ArgumentError("Class '%s' is not a new-style class" % class_.__name__)
             
         if isinstance(table, sql.Select):
             # some db's, noteably postgres, dont want to select from a select
@@ -55,7 +56,7 @@ class Mapper(object):
             # the configured properties on the mapper are not matched against the alias 
             # we make, theres workarounds but it starts to get really crazy (its crazy enough
             # the SQL that gets generated) so just require an alias
-            raise TypeError("Mapping against a Select object requires that it has a name.  Use an alias to give it a name, i.e. s = select(...).alias('myselect')")
+            raise ArgumentError("Mapping against a Select object requires that it has a name.  Use an alias to give it a name, i.e. s = select(...).alias('myselect')")
         else:
             self.table = table
 
@@ -87,7 +88,7 @@ class Mapper(object):
                 except KeyError:
                     l = self.pks_by_table.setdefault(t, util.HashSet(ordered=True))
                 if not len(t.primary_key):
-                    raise ValueError("Table " + t.name + " has no primary key columns. Specify primary_key argument to mapper.")
+                    raise ArgumentError("Table " + t.name + " has no primary key columns. Specify primary_key argument to mapper.")
                 for k in t.primary_key:
                     l.append(k)
 
@@ -110,14 +111,14 @@ class Mapper(object):
                     try:
                         prop = self.table._get_col_by_original(prop)
                     except KeyError:
-                        raise ValueError("Column '%s' is not represented in mapper's table" % prop._label)
+                        raise ArgumentError("Column '%s' is not represented in mapper's table" % prop._label)
                     self.columns[key] = prop
                     prop = ColumnProperty(prop)
                 elif isinstance(prop, list) and sql.is_column(prop[0]):
                     try:
                         prop = [self.table._get_col_by_original(p) for p in prop]
                     except KeyError, e:
-                        raise ValueError("Column '%s' is not represented in mapper's table" % e.args[0])
+                        raise ArgumentError("Column '%s' is not represented in mapper's table" % e.args[0])
                     self.columns[key] = prop[0]
                     prop = ColumnProperty(*prop)
                 self.props[key] = prop
@@ -143,7 +144,7 @@ class Mapper(object):
                 prop.columns.append(column)
             else:
                 if not allow_column_override:
-                    raise ValueError("WARNING: column '%s' not being added due to property '%s'.  Specify 'allow_column_override=True' to mapper() to ignore this condition." % (column.key, repr(prop)))
+                    raise ArgumentError("WARNING: column '%s' not being added due to property '%s'.  Specify 'allow_column_override=True' to mapper() to ignore this condition." % (column.key, repr(prop)))
                 else:
                     continue
         
@@ -358,7 +359,7 @@ class Mapper(object):
                 continue
             c = self._get_criterion(key, value)
             if c is None:
-                raise "Cant find criterion for property '"+ key + "'"
+                raise InvalidRequestError("Cant find criterion for property '"+ key + "'")
             if clause is None:
                 clause = c
             else:                
@@ -448,9 +449,9 @@ class Mapper(object):
         except KeyError:
             try:
                 prop = self.props[column.key]
-                raise "Column '%s.%s' is not available, due to conflicting property '%s':%s" % (column.table.name, column.name, column.key, repr(prop))
+                raise InvalidRequestError("Column '%s.%s' is not available, due to conflicting property '%s':%s" % (column.table.name, column.name, column.key, repr(prop)))
             except KeyError:
-                raise "No column %s.%s is configured on mapper %s..." % (column.table.name, column.name, str(self))
+                raise InvalidRequestError("No column %s.%s is configured on mapper %s..." % (column.table.name, column.name, str(self)))
         return prop[0]
         
     def _getattrbycolumn(self, obj, column):
@@ -560,7 +561,7 @@ class Mapper(object):
                     self.extension.after_update(self, obj)
                     rows += c.cursor.rowcount
                 if table.engine.supports_sane_rowcount() and rows != len(update):
-                    raise "ConcurrencyError - updated rowcount %d does not match number of objects updated %d" % (rows, len(update))
+                    raise CommitError("ConcurrencyError - updated rowcount %d does not match number of objects updated %d" % (rows, len(update)))
             if len(insert):
                 statement = table.insert()
                 for rec in insert:
@@ -607,7 +608,7 @@ class Mapper(object):
                 statement = table.delete(clause)
                 c = statement.execute(*delete)
                 if table.engine.supports_sane_rowcount() and c.rowcount != len(delete):
-                    raise "ConcurrencyError - updated rowcount %d does not match number of objects updated %d" % (c.cursor.rowcount, len(delete))
+                    raise CommitError("ConcurrencyError - updated rowcount %d does not match number of objects updated %d" % (c.cursor.rowcount, len(delete)))
 
     def _has_pks(self, table):
         try:
index a3aac738b6a8ee1a991a18356ed28cf7a8a04e52..aa8e9fe2ec25689b1f8b9cde87a1cd09a6443ee6 100644 (file)
@@ -83,7 +83,7 @@ class Session(object):
         return (class_, table.hash_key(), tuple([row[column] for column in primary_key]))
     get_row_key = staticmethod(get_row_key)
 
-    class UOWTrans(object):
+    class SessionTrans(object):
         def __init__(self, parent, uow, isactive):
             self.__parent = parent
             self.__isactive = isactive
@@ -94,20 +94,25 @@ class Session(object):
         def begin(self):
             return self.parent.begin()
         def commit(self):
+            """commits the transaction noted by this SessionTrans object."""
             self.__parent._trans_commit(self)
             self.__isactive = False
         def rollback(self):
+            """rolls back the current UnitOfWork transaction, in the case that begin()
+            has been called.  The changes logged since the begin() call are discarded."""
             self.__parent._trans_rollback(self)
             self.__isactive = False
 
     def begin(self):
-        """begins a new UnitOfWork transaction.  the next commit will affect only
-        objects that are created, modified, or deleted following the begin statement."""
+        """begins a new UnitOfWork transaction and returns a tranasaction-holding
+        object.  commit() or rollback() should be called on the returned object.
+        commit() on the Session will do nothing while a transaction is pending, and further
+        calls to begin() will return no-op transactional objects."""
         if self.parent_uow is not None:
-            return Session.UOWTrans(self, self.uow, False)
+            return Session.SessionTrans(self, self.uow, False)
         self.parent_uow = self.uow
         self.uow = UnitOfWork(identity_map = self.uow.identity_map)
-        return Session.UOWTrans(self, self.uow, True)
+        return Session.SessionTrans(self, self.uow, True)
     
     def _trans_commit(self, trans):
         if trans.uow is self.uow and trans.isactive:
@@ -120,10 +125,9 @@ class Session(object):
             self.parent_uow = None
                         
     def commit(self, *objects):
-        """commits the current UnitOfWork transaction.  if a transaction was begun 
-        via begin(), commits only those objects that were created, modified, or deleted
-        since that begin statement.  otherwise commits all objects that have been
-        changed.
+        """commits the current UnitOfWork transaction.  called with
+        no arguments, this is only used
+        for "implicit" transactions when there was no begin().
         if individual objects are submitted, then only those objects are committed, and the 
         begin/commit cycle is not affected."""
         # if an object list is given, commit just those but dont
@@ -134,15 +138,6 @@ class Session(object):
         if self.parent_uow is None:
             self.uow.commit()
 
-    def rollback(self):
-        """rolls back the current UnitOfWork transaction, in the case that begin()
-        has been called.  The changes logged since the begin() call are discarded."""
-        if self.parent_uow is None:
-            raise "UOW transaction is not begun"
-        self.uow = self.parent_uow
-        self.parent_uow = None
-        self.begin_count = 0
-        
     def register_clean(self, obj):
         self._bind_to(obj)
         self.uow.register_clean(obj)
@@ -252,7 +247,7 @@ class UOWListElement(attributes.ListElement):
     def list_value_changed(self, obj, key, item, listval, isdelete):
         sess = get_session(obj)
         if not isdelete and sess.deleted.contains(item):
-            raise "re-inserting a deleted value into a list"
+            raise InvalidRequestError("re-inserting a deleted value into a list")
         sess.modified_lists.append(self)
         if self.deleteremoved and isdelete:
             sess.register_deleted(item)
@@ -461,7 +456,7 @@ class UOWTransaction(object):
         # things can get really confusing if theres duplicate instances floating around,
         # so make sure everything is OK
         if hasattr(obj, '_instance_key') and not self.uow.identity_map.has_key(obj._instance_key):
-            raise "Detected a mapped object not present in the current thread's Identity Map: '%s'.  Use objectstore.import_instance() to place deserialized instances or instances from other threads" % repr(obj._instance_key)
+            raise InvalidRequestError("Detected a mapped object not present in the current thread's Identity Map: '%s'.  Use objectstore.import_instance() to place deserialized instances or instances from other threads" % repr(obj._instance_key))
             
         mapper = object_mapper(obj)
         self.mappers.append(mapper)
@@ -1016,7 +1011,7 @@ def get_session(obj=None):
             try:
                 return _sessions[hashkey]
             except KeyError:
-                raise "Session '%s' referenced by object '%s' no longer exists" % (hashkey, repr(obj))
+                raise InvalidRequestError("Session '%s' referenced by object '%s' no longer exists" % (hashkey, repr(obj)))
 
     return session_registry()
 
index f686e588c453d9fd5525c110374f14658be02c30..65f9cbdc267ff0133ec0798784a77932236e7946 100644 (file)
@@ -16,6 +16,7 @@ import sqlalchemy.util as util
 import sqlalchemy.attributes as attributes
 import mapper
 import objectstore
+from sqlalchemy.exceptions import *
 
 class ColumnProperty(MapperProperty):
     """describes an object attribute that corresponds to a table column."""
@@ -161,7 +162,7 @@ class PropertyLoader(MapperProperty):
         self.parent = parent
 
         if self.secondaryjoin is not None and self.secondary is None:
-            raise ValueError("Property '" + self.key + "' specified with secondary join condition but no secondary argument")
+            raise ArgumentError("Property '" + self.key + "' specified with secondary join condition but no secondary argument")
         # if join conditions were not specified, figure them out based on foreign keys
         if self.secondary is not None:
             if self.secondaryjoin is None:
@@ -209,7 +210,7 @@ class PropertyLoader(MapperProperty):
                     if not self.mapper.props[self.backref].is_backref:
                         self.is_backref=True
         elif not objectstore.global_attributes.is_class_managed(parent.class_, key):
-            raise "Non-primary property created for attribute '%s' on class '%s', but that attribute is not managed! Insure that the primary mapper for this class defines this property" % (key, parent.class_.__name__)
+            raise ArgumentError("Non-primary property created for attribute '%s' on class '%s', but that attribute is not managed! Insure that the primary mapper for this class defines this property" % (key, parent.class_.__name__))
 
         self.do_init_subclass(key, parent)
         
@@ -231,7 +232,7 @@ class PropertyLoader(MapperProperty):
         elif self.foreigntable == self.parent.table:
             return PropertyLoader.MANYTOONE
         else:
-            raise "Cant determine relation direction"
+            raise ArgumentError("Cant determine relation direction")
             
     def _find_dependent(self):
         """searches through the primary join condition to determine which side
@@ -245,18 +246,18 @@ class PropertyLoader(MapperProperty):
                 return
             if isinstance(binary.left, schema.Column) and binary.left.primary_key:
                 if dependent[0] is binary.left.table:
-                    raise "bidirectional dependency not supported...specify foreignkey"
+                    raise ArgumentError("bidirectional dependency not supported...specify foreignkey")
                 dependent[0] = binary.right.table
                 self.foreignkey= binary.right
             elif isinstance(binary.right, schema.Column) and binary.right.primary_key:
                 if dependent[0] is binary.right.table:
-                    raise "bidirectional dependency not supported...specify foreignkey"
+                    raise ArgumentError("bidirectional dependency not supported...specify foreignkey")
                 dependent[0] = binary.left.table
                 self.foreignkey = binary.left
         visitor = BinaryVisitor(foo)
         self.primaryjoin.accept_visitor(visitor)
         if dependent[0] is None:
-            raise "cant determine primary foreign key in the join relationship....specify foreignkey=<column> or foreignkey=[<columns>]"
+            raise ArgumentError("cant determine primary foreign key in the join relationship....specify foreignkey=<column> or foreignkey=[<columns>]")
         else:
             self.foreigntable = dependent[0]
 
@@ -358,7 +359,7 @@ class PropertyLoader(MapperProperty):
             uowcommit.register_processor(stub, self, self.parent, True)
         elif self.direction == PropertyLoader.ONETOMANY:
             if self.post_update:
-                raise "post_update not yet supported with one-to-many relation"
+                raise InvalidRequestError("post_update not yet supported with one-to-many relation")
             uowcommit.register_dependency(self.parent, self.mapper)
             uowcommit.register_processor(self.parent, self, self.parent, False)
             uowcommit.register_processor(self.parent, self, self.parent, True)
@@ -372,7 +373,7 @@ class PropertyLoader(MapperProperty):
                 uowcommit.register_dependency(self.mapper, self.parent)
                 uowcommit.register_processor(self.mapper, self, self.parent, False)
         else:
-            raise " no foreign key ?"
+            raise AssertionError(" no foreign key ?")
 
     def get_object_dependencies(self, obj, uowcommit, passive = True):
         return uowcommit.uow.attributes.get_history(obj, self.key, passive = passive)
@@ -547,13 +548,13 @@ class PropertyLoader(MapperProperty):
                     source = binary.right
                     dest = binary.left
                 else:
-                    raise "Cant determine direction for relationship %s = %s" % (binary.left.fullname, binary.right.fullname)
+                    raise ArgumentError("Cant determine direction for relationship %s = %s" % (binary.left.fullname, binary.right.fullname))
                 if self.direction == PropertyLoader.ONETOMANY:
                     self.syncrules.append(SyncRule(self.parent, source, dest, dest_mapper=self.mapper))
                 elif self.direction == PropertyLoader.MANYTOONE:
                     self.syncrules.append(SyncRule(self.mapper, source, dest, dest_mapper=self.parent))
                 else:
-                    raise "assert failed"
+                    raise AssertionError("assert failed")
             else:
                 pt = check_for_table(binary, parent_tables)
                 tt = check_for_table(binary, target_tables)
@@ -567,7 +568,7 @@ class PropertyLoader(MapperProperty):
                     elif self.direction == PropertyLoader.MANYTOONE:
                         self.syncrules.append(SyncRule(self.mapper, tt, pt, dest_mapper=self.parent))
                     else:
-                        raise "assert failed"
+                        raise AssertionError("assert failed")
                 elif pt and st:
                     self.syncrules.append(SyncRule(self.parent, pt, st, direction=PropertyLoader.ONETOMANY))
                 elif tt and st:
@@ -579,7 +580,7 @@ class PropertyLoader(MapperProperty):
         if self.secondaryjoin is not None:
             self.secondaryjoin.accept_visitor(processor)
         if len(self.syncrules) == 0:
-            raise "No syncrules generated for join criterion " + str(self.primaryjoin)
+            raise ArgumentError("No syncrules generated for join criterion " + str(self.primaryjoin))
 
     def _synchronize(self, obj, child, associationrow, clearkeys):
         """called during a commit to execute the full list of syncrules on the 
@@ -799,7 +800,7 @@ class EagerLoader(PropertyLoader):
                         self.mapper.props[prop.key] = p
 
                         if recursion_stack.has_key(prop):
-                            raise "Circular eager load relationship detected on " + str(self.mapper) + " " + key + repr(self.mapper.props)
+                            raise ArgumentError("Circular eager load relationship detected on " + str(self.mapper) + " " + key + repr(self.mapper.props))
 
                         p.do_init_subclass(prop.key, prop.parent, recursion_stack)
 
@@ -852,7 +853,7 @@ class EagerLoader(PropertyLoader):
         try:
             for key, value in self.mapper.props.iteritems():
                 if recursion_stack.has_key(value):
-                    raise "Circular eager load relationship detected on " + str(self.mapper) + " " + key + repr(self.mapper.props)
+                    raise InvalidRequestError("Circular eager load relationship detected on " + str(self.mapper) + " " + key + repr(self.mapper.props))
                 value.setup(key, statement, recursion_stack=recursion_stack, eagertable=self.eagertarget)
         finally:
             del recursion_stack[self]
index e6d4b6b5777f093068d0ea7381a5f1b65e86fc03..95807bf5f269f2298e9172d7521170371a41d004 100644 (file)
@@ -33,6 +33,7 @@ realized this characteristic of the algorithm.
 import string, StringIO
 from sets import *
 import sqlalchemy.util as util
+from sqlalchemy.exceptions import *
 
 class QueueDependencySorter(object):
     """this is a topological sort from wikipedia.  its very stable.  it creates a straight-line
@@ -91,7 +92,7 @@ class QueueDependencySorter(object):
                     n.cycles = Set([n])
                     continue
                 else:
-                    raise "Self-referential dependency detected " + repr(t)
+                    raise CommitError("Self-referential dependency detected " + repr(t))
             childnode = nodes[t[1]]
             parentnode = nodes[t[0]]
             self._add_edge(edges, (parentnode, childnode))
@@ -125,7 +126,7 @@ class QueueDependencySorter(object):
                     continue
                 else:
                     # long cycles not allowed
-                    raise "Circular dependency detected " + repr(edges) + repr(queue)
+                    raise CommitError("Circular dependency detected " + repr(edges) + repr(queue))
             node = queue.pop()
             if not hasattr(node, '_cyclical'):
                 output.append(node)
@@ -291,7 +292,7 @@ class TreeDependencySorter(object):
             elif parentnode.is_descendant_of(childnode):
                 # check for a line thats backwards with nodes in between, this is a 
                 # circular dependency (although confirmation on this would be helpful)
-                raise "Circular dependency detected"
+                raise CommitError("Circular dependency detected")
             elif not childnode.is_descendant_of(parentnode):
                 # if relationship doesnt exist, connect nodes together
                 root = childnode.get_sibling_ancestor(parentnode)
index a9c6a4d96869dfad6ee1f656c422f2761cea64ab..12b3c7707fec2d13778ff6da27f7f23835cd07b3 100644 (file)
@@ -15,8 +15,9 @@ the schema package "plugs in" to the SQL package.
 
 """
 
-from sqlalchemy.util import *
-from sqlalchemy.types import *
+from util import *
+from types import *
+from exceptions import *
 import copy, re, string
 
 __all__ = ['SchemaItem', 'Table', 'Column', 'ForeignKey', 'Sequence', 'Index',
@@ -76,11 +77,11 @@ class TableSingleton(type):
                 if redefine:
                     table.reload_values(*args)
                 elif not useexisting:
-                    raise "Table '%s.%s' is already defined. specify 'redefine=True' to remap columns, or 'useexisting=True' to use the existing table" % (schema, name)
+                    raise ArgumentError("Table '%s.%s' is already defined. specify 'redefine=True' to remap columns, or 'useexisting=True' to use the existing table" % (schema, name))
             return table
         except KeyError:
             if mustexist:
-                raise "Table '%s.%s' not defined" % (schema, name)
+                raise ArgumentError("Table '%s.%s' not defined" % (schema, name))
             table = type.__call__(self, name, engine, **kwargs)
             engine.tables[key] = table
             # load column definitions from the database if 'autoload' is defined
@@ -248,7 +249,7 @@ class Column(SchemaItem):
         self.foreign_key = None
         self._orig = None
         if len(kwargs):
-            raise "Unknown arguments passed to Column: " + repr(kwargs.keys())
+            raise ArgumentError("Unknown arguments passed to Column: " + repr(kwargs.keys()))
         
     original = property(lambda s: s._orig or s)
     engine = property(lambda s: s.table.engine)
@@ -272,7 +273,7 @@ class Column(SchemaItem):
             
     def _set_parent(self, table):
         if getattr(self, 'table', None) is not None:
-            raise "this Column already has a table!"
+            raise ArgumentError("this Column already has a table!")
         if not self.hidden:
             table.columns[self.key] = self
             if self.primary_key:
@@ -377,7 +378,7 @@ class ForeignKey(SchemaItem):
             if isinstance(self._colspec, str):
                 m = re.match(r"^([\w_-]+)(?:\.([\w_-]+))?(?:\.([\w_-]+))?$", self._colspec)
                 if m is None:
-                    raise ValueError("Invalid foreign key column specification: " + self._colspec)
+                    raise ArgumentError("Invalid foreign key column specification: " + self._colspec)
                 if m.group(3) is None:
                     (tname, colname) = m.group(1, 2)
                     schema = self.parent.original.table.schema
@@ -485,7 +486,7 @@ class Index(SchemaItem):
                 self.table = column.table
             elif column.table != self.table:
                 # all columns muse be from same table
-                raise ValueError("All index columns must be from same table. "
+                raise ArgumentError("All index columns must be from same table. "
                                  "%s is from %s not %s" % (column,
                                                            column.table,
                                                            self.table))
index 03c94c5e339251a8e88f814333528722203f6116..9b35713849dbcd177fb813bbf5893cdf70bb9ddc 100644 (file)
@@ -6,9 +6,10 @@
 
 """defines the base components of SQL expression trees."""
 
-import sqlalchemy.schema as schema
-import sqlalchemy.util as util
-import sqlalchemy.types as sqltypes
+import schema
+import util
+import types as sqltypes
+from exceptions import *
 import string, re, random
 types = __import__('types')
 
@@ -379,7 +380,7 @@ class ClauseElement(object):
             engine = self.engine
 
         if engine is None:
-            raise "no SQLEngine could be located within this ClauseElement."
+            raise InvalidRequestError("no SQLEngine could be located within this ClauseElement.")
 
         return engine.compile(self, parameters=parameters, typemap=typemap)
 
@@ -475,7 +476,7 @@ class CompareMixin(object):
         if _is_literal(obj):
             if obj is None:
                 if operator != '=':
-                    raise "Only '=' operator can be used with NULL"
+                    raise ArgumentError("Only '=' operator can be used with NULL")
                 return BooleanExpression(self._compare_self(), null(), 'IS')
             else:
                 obj = self._bind_param(obj)
@@ -857,7 +858,7 @@ class Join(FromClause):
                     crit.append(secondary._get_col_by_original(fk.column) == fk.parent)
                     self.foreignkey = fk.parent
         if len(crit) == 0:
-            raise "Cant find any foreign key relationships between '%s' (%s) and '%s' (%s)" % (primary.name, repr(primary), secondary.name, repr(secondary))
+            raise ArgumentError("Cant find any foreign key relationships between '%s' (%s) and '%s' (%s)" % (primary.name, repr(primary), secondary.name, repr(secondary)))
         elif len(crit) == 1:
             return (crit[0])
         else:
@@ -1043,7 +1044,7 @@ class ColumnImpl(ColumnElement):
         if engine is None:
             engine = self.engine
         if engine is None:
-            raise "no SQLEngine could be located within this ClauseElement."
+            raise InvalidRequestError("no SQLEngine could be located within this ClauseElement.")
         return engine.compile(self.column, parameters=parameters, typemap=typemap)
 
 class TableImpl(FromClause):
index 633091dd3220842e0731744463bb3cd0c3130659..301db0ec4da3c2a82dab4c6aa8e651df0314b3ea 100644 (file)
@@ -6,6 +6,7 @@
 
 __all__ = ['OrderedProperties', 'OrderedDict', 'generic_repr', 'HashSet']
 import thread, weakref, UserList,string, inspect
+from exceptions import *
 
 def to_list(x):
     if x is None:
@@ -257,7 +258,7 @@ class HistoryArraySet(UserList.UserList):
         return id(self)
     def _setrecord(self, item):
         if self.readonly:
-            raise "This list is read only"
+            raise InvalidRequestError("This list is read only")
         try:
             val = self.records[item]
             if val is True or val is None:
@@ -270,7 +271,7 @@ class HistoryArraySet(UserList.UserList):
             return True
     def _delrecord(self, item):
         if self.readonly:
-            raise "This list is read only"
+            raise InvalidRequestError("This list is read only")
         try:
             val = self.records[item]
             if val is None:
@@ -428,7 +429,7 @@ def constructor_args(instance, **kwargs):
             if hasattr(instance, arg):
                 newparams[arg] = getattr(instance, arg)
             else:
-                raise "instance has no attribute '%s'" % arg
+                raise AssertionError("instance has no attribute '%s'" % arg)
 
     return newparams
     
\ No newline at end of file
index 69f632f1f4caf47c567780363f1d906125e87dd5..863d30fd9505bd8986b2b75f01e8b3c25385a675 100644 (file)
@@ -249,7 +249,7 @@ class CycleTest2(AssertMixin):
         p = Person()
         p.balls.append(b)
         p.favorateBall = b
-        #objectstore.commit()
+        objectstore.commit()
 
         
 if __name__ == "__main__":
index 8c4a7485feb63ed8f70e8815a1a8fe59f2718a96..2dabc8b670265461e54e85e39fbe77341bea8940 100644 (file)
@@ -148,10 +148,10 @@ class MapperTest(MapperSuperTest):
         # assert that overriding a column raises an error
         try:
             m = mapper(User, users, properties = {
-                    'user_name' : relation(Address, addresses),
+                    'user_name' : relation(mapper(Address, addresses)),
                 })
-            self.assert_(False, "should have raised ValueError")
-        except ValueError, e:
+            self.assert_(False, "should have raised ArgumentError")
+        except ArgumentError, e:
             self.assert_(True)
             
         # assert that allow_column_override cancels the error
index a117b4112fedcf88e655a40bcc9577ca9676d25c..687c9b10283effbb1b75f980a656e14b0368e3da 100644 (file)
@@ -7,7 +7,6 @@ import testbase
 from tables import *
 import tables
 
-
 class HistoryTest(AssertMixin):
     def setUpAll(self):
         db.echo = False