From: Mike Bayer Date: Fri, 12 Feb 2010 19:54:49 +0000 (+0000) Subject: - Made sqlalchemy.sql.expressions.Executable part of public X-Git-Tag: rel_0_6beta2~207 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d0d5f792404126f2f3f62cb850e6b887c246178e;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Made sqlalchemy.sql.expressions.Executable part of public API, used for any expression construct that can be sent to execute(). FunctionElement now inherits Executable so that it gains execution_options(), which are also propagated to the select() that's generated within execute(). Executable in turn subclasses _Generative which marks any ClauseElement that supports the @_generative decorator - these may also become "public" for the benefit of the compiler extension at some point. --- diff --git a/CHANGES b/CHANGES index ebbd60b38f..7857c51363 100644 --- a/CHANGES +++ b/CHANGES @@ -71,6 +71,16 @@ CHANGES types, before falling back to that of the known type on the other side of the expression. Also part of [ticket:1683]. + + - Made sqlalchemy.sql.expressions.Executable part of public + API, used for any expression construct that can be sent to + execute(). FunctionElement now inherits Executable so that + it gains execution_options(), which are also propagated + to the select() that's generated within execute(). + Executable in turn subclasses _Generative which marks + any ClauseElement that supports the @_generative + decorator - these may also become "public" for the benefit + of the compiler extension at some point. - mysql - Fixed reflection bug whereby when COLLATE was present, diff --git a/doc/build/reference/sqlalchemy/expressions.rst b/doc/build/reference/sqlalchemy/expressions.rst index 1c3c208b46..84210f04af 100644 --- a/doc/build/reference/sqlalchemy/expressions.rst +++ b/doc/build/reference/sqlalchemy/expressions.rst @@ -152,6 +152,10 @@ Classes :members: where :show-inheritance: +.. autoclass:: Executable + :members: + :show-inheritance: + .. autoclass:: FunctionElement :members: :show-inheritance: diff --git a/lib/sqlalchemy/ext/compiler.py b/lib/sqlalchemy/ext/compiler.py index 7861096f9e..3226b0efd8 100644 --- a/lib/sqlalchemy/ext/compiler.py +++ b/lib/sqlalchemy/ext/compiler.py @@ -64,7 +64,9 @@ in-progress compilation, including ``compiler.dialect``, and :class:`~sqlalchemy.sql.compiler.DDLCompiler` both include a ``process()`` method which can be used for compilation of embedded attributes:: - class InsertFromSelect(ClauseElement): + from sqlalchemy.sql.expression import Executable, ClauseElement + + class InsertFromSelect(Executable, ClauseElement): def __init__(self, table, select): self.table = table self.select = select @@ -154,6 +156,11 @@ A big part of using the compiler extension is subclassing SQLAlchemy expression ``execute_at()`` method, allowing the construct to be invoked during CREATE TABLE and DROP TABLE sequences. +* :class:`~sqlalchemy.sql.expression.Executable` - This is a mixin which should be + used with any expression class that represents a "standalone" SQL statement that + can be passed directly to an ``execute()`` method. It is already implicit + within ``DDLElement`` and ``FunctionElement``. + """ def compiles(class_, *specs): diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index c345b0b21e..d51ae3a458 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -2030,10 +2030,10 @@ class SchemaVisitor(visitors.ClauseVisitor): __traverse_options__ = {'schema_visitor':True} -class DDLElement(expression._Executable, expression.ClauseElement): +class DDLElement(expression.Executable, expression.ClauseElement): """Base class for DDL expression constructs.""" - _execution_options = expression._Executable.\ + _execution_options = expression.Executable.\ _execution_options.union({'autocommit':True}) target = None diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 1ae706999e..0f55ac097d 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -2208,7 +2208,20 @@ class _TypeClause(ClauseElement): def __init__(self, type): self.type = type -class _Executable(object): + +class _Generative(object): + """Allow a ClauseElement to generate itself via the + @_generative decorator. + + """ + + def _generate(self): + s = self.__class__.__new__(self.__class__) + s.__dict__ = self.__dict__.copy() + return s + + +class Executable(_Generative): """Mark a ClauseElement as supporting execution.""" supports_execution = True @@ -2240,8 +2253,10 @@ class _Executable(object): """ self._execution_options = self._execution_options.union(kw) +# legacy, some outside users may be calling this +_Executable = Executable -class _TextClause(_Executable, ClauseElement): +class _TextClause(Executable, ClauseElement): """Represent a literal SQL text fragment. Public constructor is the :func:`text()` function. @@ -2251,7 +2266,7 @@ class _TextClause(_Executable, ClauseElement): __visit_name__ = 'textclause' _bind_params_regex = re.compile(r'(?