From: Mike Bayer Date: Fri, 2 Feb 2007 18:18:31 +0000 (+0000) Subject: - added a "supports_execution()" method to ClauseElement, so that individual X-Git-Tag: rel_0_3_5~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f39a37bfd49f5b4abce3670d5191be8cdb8da29;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - added a "supports_execution()" method to ClauseElement, so that individual kinds of clauses can express if they are appropriate for executing...such as, you can execute a "select", but not a "Table" or a "Join". --- diff --git a/CHANGES b/CHANGES index 9b12671a58..f4338c6814 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,9 @@ object might be label'ed as something else which does contain mixed case, and propigating "case_sensitive=False" breaks that. Other fixes to quoting when using labels and "fake" column objects + - added a "supports_execution()" method to ClauseElement, so that individual + kinds of clauses can express if they are appropriate for executing...such as, + you can execute a "select", but not a "Table" or a "Join". - orm: - further rework of the recent polymorphic relationship refactorings, as well as the mechanics of relationships overall. Allows more accurate ORM behavior diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index c7b5d93fe6..69d9ef9556 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -287,6 +287,8 @@ class Connection(Connectable): return self.execute_compiled(elem.compile(engine=self.__engine, parameters=param), *multiparams, **params) def execute_compiled(self, compiled, *multiparams, **params): """executes a sql.Compiled object.""" + if not compiled.can_execute: + raise exceptions.ArgumentError("Not an executeable clause: %s" % (str(compiled))) cursor = self.__engine.dialect.create_cursor(self.connection) parameters = [compiled.get_params(**m) for m in self._params_to_listofdicts(*multiparams, **params)] if len(parameters) == 1: diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py index ee1dce9f86..53cb6b9771 100644 --- a/lib/sqlalchemy/sql.py +++ b/lib/sqlalchemy/sql.py @@ -387,7 +387,8 @@ class Compiled(ClauseVisitor): self.statement = statement self.parameters = parameters self.engine = engine - + self.can_execute = statement.supports_execution() + def compile(self): self.statement.accept_visitor(self) self.after_compile() @@ -439,6 +440,10 @@ class ClauseElement(object): """accept a ClauseVisitor and call the appropriate visit_xxx method.""" raise NotImplementedError(repr(self)) + def supports_execution(self): + """return True if this clause element represents a complete executable statement""" + return False + def copy_container(self): """return a copy of this ClauseElement, iff this ClauseElement contains other ClauseElements. @@ -888,7 +893,9 @@ class _TextClause(ClauseElement): visitor.visit_textclause(self) def _get_from_objects(self): return [] - + def supports_execution(self): + return True + class _Null(ColumnElement): """represents the NULL keyword in a SQL statement. public contstructor is the null() function.""" @@ -1193,7 +1200,8 @@ class Alias(FromClause): alias = alias + "_" + hex(random.randint(0, 65535))[2:] self.name = alias self.case_sensitive = getattr(baseselectable, "case_sensitive", alias.lower() != alias) - + def supports_execution(self): + return self.original.supports_execution() def _locate_oid_column(self): if self.selectable.oid_column is not None: return self.selectable.oid_column._make_proxy(self) @@ -1346,6 +1354,8 @@ class TableClause(FromClause): class _SelectBaseMixin(object): """base class for Select and CompoundSelects""" + def supports_execution(self): + return True def order_by(self, *clauses): if len(clauses) == 1 and clauses[0] is None: self.order_by_clause = ClauseList() @@ -1644,6 +1654,8 @@ class Select(_SelectBaseMixin, FromClause): class _UpdateBase(ClauseElement): """forms the base for INSERT, UPDATE, and DELETE statements.""" + def supports_execution(self): + return True def _process_colparams(self, parameters): """receives the "values" of an INSERT or UPDATE statement and constructs appropriate bind parameters."""