summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-02-19 00:19:16 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-02-19 00:19:16 +0000
commitf1a68f37fa9aea41d21049307fef840f9b6a0116 (patch)
treed762e8e262f0ed6d31c689912fdb82dc55771ad1 /lib
parent2d5e6eb93b08961d557399899a51dac225832716 (diff)
downloadsqlalchemy-f1a68f37fa9aea41d21049307fef840f9b6a0116.tar.gz
exception package added, support throughout
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlalchemy/__init__.py1
-rw-r--r--lib/sqlalchemy/ansisql.py2
-rw-r--r--lib/sqlalchemy/attributes.py2
-rw-r--r--lib/sqlalchemy/engine.py24
-rw-r--r--lib/sqlalchemy/exceptions.py41
-rw-r--r--lib/sqlalchemy/mapping/__init__.py5
-rw-r--r--lib/sqlalchemy/mapping/mapper.py23
-rw-r--r--lib/sqlalchemy/mapping/objectstore.py37
-rw-r--r--lib/sqlalchemy/mapping/properties.py29
-rw-r--r--lib/sqlalchemy/mapping/topological.py7
-rw-r--r--lib/sqlalchemy/schema.py17
-rw-r--r--lib/sqlalchemy/sql.py15
-rw-r--r--lib/sqlalchemy/util.py7
13 files changed, 126 insertions, 84 deletions
diff --git a/lib/sqlalchemy/__init__.py b/lib/sqlalchemy/__init__.py
index 29b2dfd60..0c8aa2fe0 100644
--- a/lib/sqlalchemy/__init__.py
+++ b/lib/sqlalchemy/__init__.py
@@ -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 *
diff --git a/lib/sqlalchemy/ansisql.py b/lib/sqlalchemy/ansisql.py
index a9c6bb207..88bd0f8bd 100644
--- a/lib/sqlalchemy/ansisql.py
+++ b/lib/sqlalchemy/ansisql.py
@@ -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):
diff --git a/lib/sqlalchemy/attributes.py b/lib/sqlalchemy/attributes.py
index f6abe6b31..7a9f13c57 100644
--- a/lib/sqlalchemy/attributes.py
+++ b/lib/sqlalchemy/attributes.py
@@ -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
diff --git a/lib/sqlalchemy/engine.py b/lib/sqlalchemy/engine.py
index d553eee2d..1ca9d00fd 100644
--- a/lib/sqlalchemy/engine.py
+++ b/lib/sqlalchemy/engine.py
@@ -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
index 000000000..6883293ec
--- /dev/null
+++ b/lib/sqlalchemy/exceptions.py
@@ -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
diff --git a/lib/sqlalchemy/mapping/__init__.py b/lib/sqlalchemy/mapping/__init__.py
index 538559e43..64258fa65 100644
--- a/lib/sqlalchemy/mapping/__init__.py
+++ b/lib/sqlalchemy/mapping/__init__.py
@@ -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):
diff --git a/lib/sqlalchemy/mapping/mapper.py b/lib/sqlalchemy/mapping/mapper.py
index 24bf11fd8..5fed7c7f2 100644
--- a/lib/sqlalchemy/mapping/mapper.py
+++ b/lib/sqlalchemy/mapping/mapper.py
@@ -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:
diff --git a/lib/sqlalchemy/mapping/objectstore.py b/lib/sqlalchemy/mapping/objectstore.py
index a3aac738b..aa8e9fe2e 100644
--- a/lib/sqlalchemy/mapping/objectstore.py
+++ b/lib/sqlalchemy/mapping/objectstore.py
@@ -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()
diff --git a/lib/sqlalchemy/mapping/properties.py b/lib/sqlalchemy/mapping/properties.py
index f686e588c..65f9cbdc2 100644
--- a/lib/sqlalchemy/mapping/properties.py
+++ b/lib/sqlalchemy/mapping/properties.py
@@ -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]
diff --git a/lib/sqlalchemy/mapping/topological.py b/lib/sqlalchemy/mapping/topological.py
index e6d4b6b57..95807bf5f 100644
--- a/lib/sqlalchemy/mapping/topological.py
+++ b/lib/sqlalchemy/mapping/topological.py
@@ -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)
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index a9c6a4d96..12b3c7707 100644
--- a/lib/sqlalchemy/schema.py
+++ b/lib/sqlalchemy/schema.py
@@ -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))
diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py
index 03c94c5e3..9b3571384 100644
--- a/lib/sqlalchemy/sql.py
+++ b/lib/sqlalchemy/sql.py
@@ -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):
diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py
index 633091dd3..301db0ec4 100644
--- a/lib/sqlalchemy/util.py
+++ b/lib/sqlalchemy/util.py
@@ -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