summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/compiler.py
diff options
context:
space:
mode:
authorDiana Clarke <diana.joan.clarke@gmail.com>2012-11-19 14:16:39 -0500
committerDiana Clarke <diana.joan.clarke@gmail.com>2012-11-19 14:16:39 -0500
commit03687b36b78be86c0f2a01eeb658c5b52fbd6c76 (patch)
tree9b8ccc3fed989ef64d41a53d091e2309836a9992 /lib/sqlalchemy/ext/compiler.py
parentef326d9fe39ab493dd4aeaf2cecf9052a04d49b7 (diff)
downloadsqlalchemy-03687b36b78be86c0f2a01eeb658c5b52fbd6c76.tar.gz
just a pep8 pass of lib/sqlalchemy/ext
Diffstat (limited to 'lib/sqlalchemy/ext/compiler.py')
-rw-r--r--lib/sqlalchemy/ext/compiler.py110
1 files changed, 63 insertions, 47 deletions
diff --git a/lib/sqlalchemy/ext/compiler.py b/lib/sqlalchemy/ext/compiler.py
index e3e668364..93984d0d1 100644
--- a/lib/sqlalchemy/ext/compiler.py
+++ b/lib/sqlalchemy/ext/compiler.py
@@ -9,8 +9,9 @@
Synopsis
========
-Usage involves the creation of one or more :class:`~sqlalchemy.sql.expression.ClauseElement`
-subclasses and one or more callables defining its compilation::
+Usage involves the creation of one or more
+:class:`~sqlalchemy.sql.expression.ClauseElement` subclasses and one or
+more callables defining its compilation::
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import ColumnClause
@@ -58,7 +59,8 @@ invoked for the dialect in use::
def visit_alter_column(element, compiler, **kw):
return "ALTER TABLE %s ALTER COLUMN %s ..." % (element.table.name, element.column.name)
-The second ``visit_alter_table`` will be invoked when any ``postgresql`` dialect is used.
+The second ``visit_alter_table`` will be invoked when any ``postgresql``
+dialect is used.
Compiling sub-elements of a custom expression construct
=======================================================
@@ -99,10 +101,11 @@ Produces::
Cross Compiling between SQL and DDL compilers
---------------------------------------------
-SQL and DDL constructs are each compiled using different base compilers - ``SQLCompiler``
-and ``DDLCompiler``. A common need is to access the compilation rules of SQL expressions
-from within a DDL expression. The ``DDLCompiler`` includes an accessor ``sql_compiler`` for this reason, such as below where we generate a CHECK
-constraint that embeds a SQL expression::
+SQL and DDL constructs are each compiled using different base compilers -
+``SQLCompiler`` and ``DDLCompiler``. A common need is to access the
+compilation rules of SQL expressions from within a DDL expression. The
+``DDLCompiler`` includes an accessor ``sql_compiler`` for this reason, such as
+below where we generate a CHECK constraint that embeds a SQL expression::
@compiles(MyConstraint)
def compile_my_constraint(constraint, ddlcompiler, **kw):
@@ -116,20 +119,22 @@ constraint that embeds a SQL expression::
Enabling Autocommit on a Construct
==================================
-Recall from the section :ref:`autocommit` that the :class:`.Engine`, when asked to execute
-a construct in the absence of a user-defined transaction, detects if the given
-construct represents DML or DDL, that is, a data modification or data definition statement, which
-requires (or may require, in the case of DDL) that the transaction generated by the DBAPI be committed
-(recall that DBAPI always has a transaction going on regardless of what SQLAlchemy does). Checking
-for this is actually accomplished
-by checking for the "autocommit" execution option on the construct. When building a construct like
-an INSERT derivation, a new DDL type, or perhaps a stored procedure that alters data, the "autocommit"
-option needs to be set in order for the statement to function with "connectionless" execution
+Recall from the section :ref:`autocommit` that the :class:`.Engine`, when
+asked to execute a construct in the absence of a user-defined transaction,
+detects if the given construct represents DML or DDL, that is, a data
+modification or data definition statement, which requires (or may require,
+in the case of DDL) that the transaction generated by the DBAPI be committed
+(recall that DBAPI always has a transaction going on regardless of what
+SQLAlchemy does). Checking for this is actually accomplished by checking for
+the "autocommit" execution option on the construct. When building a
+construct like an INSERT derivation, a new DDL type, or perhaps a stored
+procedure that alters data, the "autocommit" option needs to be set in order
+for the statement to function with "connectionless" execution
(as described in :ref:`dbengine_implicit`).
-Currently a quick way to do this is to subclass :class:`.Executable`, then add the "autocommit" flag
-to the ``_execution_options`` dictionary (note this is a "frozen" dictionary which supplies a generative
-``union()`` method)::
+Currently a quick way to do this is to subclass :class:`.Executable`, then
+add the "autocommit" flag to the ``_execution_options`` dictionary (note this
+is a "frozen" dictionary which supplies a generative ``union()`` method)::
from sqlalchemy.sql.expression import Executable, ClauseElement
@@ -137,8 +142,9 @@ to the ``_execution_options`` dictionary (note this is a "frozen" dictionary whi
_execution_options = \\
Executable._execution_options.union({'autocommit': True})
-More succinctly, if the construct is truly similar to an INSERT, UPDATE, or DELETE, :class:`.UpdateBase`
-can be used, which already is a subclass of :class:`.Executable`, :class:`.ClauseElement` and includes the
+More succinctly, if the construct is truly similar to an INSERT, UPDATE, or
+DELETE, :class:`.UpdateBase` can be used, which already is a subclass
+of :class:`.Executable`, :class:`.ClauseElement` and includes the
``autocommit`` flag::
from sqlalchemy.sql.expression import UpdateBase
@@ -150,7 +156,8 @@ can be used, which already is a subclass of :class:`.Executable`, :class:`.Claus
-DDL elements that subclass :class:`.DDLElement` already have the "autocommit" flag turned on.
+DDL elements that subclass :class:`.DDLElement` already have the
+"autocommit" flag turned on.
@@ -158,13 +165,16 @@ DDL elements that subclass :class:`.DDLElement` already have the "autocommit" fl
Changing the default compilation of existing constructs
=======================================================
-The compiler extension applies just as well to the existing constructs. When overriding
-the compilation of a built in SQL construct, the @compiles decorator is invoked upon
-the appropriate class (be sure to use the class, i.e. ``Insert`` or ``Select``, instead of the creation function such as ``insert()`` or ``select()``).
+The compiler extension applies just as well to the existing constructs. When
+overriding the compilation of a built in SQL construct, the @compiles
+decorator is invoked upon the appropriate class (be sure to use the class,
+i.e. ``Insert`` or ``Select``, instead of the creation function such
+as ``insert()`` or ``select()``).
-Within the new compilation function, to get at the "original" compilation routine,
-use the appropriate visit_XXX method - this because compiler.process() will call upon the
-overriding routine and cause an endless loop. Such as, to add "prefix" to all insert statements::
+Within the new compilation function, to get at the "original" compilation
+routine, use the appropriate visit_XXX method - this
+because compiler.process() will call upon the overriding routine and cause
+an endless loop. Such as, to add "prefix" to all insert statements::
from sqlalchemy.sql.expression import Insert
@@ -172,14 +182,16 @@ overriding routine and cause an endless loop. Such as, to add "prefix" to all
def prefix_inserts(insert, compiler, **kw):
return compiler.visit_insert(insert.prefix_with("some prefix"), **kw)
-The above compiler will prefix all INSERT statements with "some prefix" when compiled.
+The above compiler will prefix all INSERT statements with "some prefix" when
+compiled.
.. _type_compilation_extension:
Changing Compilation of Types
=============================
-``compiler`` works for types, too, such as below where we implement the MS-SQL specific 'max' keyword for ``String``/``VARCHAR``::
+``compiler`` works for types, too, such as below where we implement the
+MS-SQL specific 'max' keyword for ``String``/``VARCHAR``::
@compiles(String, 'mssql')
@compiles(VARCHAR, 'mssql')
@@ -248,10 +260,10 @@ A synopsis is as follows:
``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``.
+* :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``.
Further Examples
================
@@ -259,12 +271,13 @@ Further Examples
"UTC timestamp" function
-------------------------
-A function that works like "CURRENT_TIMESTAMP" except applies the appropriate conversions
-so that the time is in UTC time. Timestamps are best stored in relational databases
-as UTC, without time zones. UTC so that your database doesn't think time has gone
-backwards in the hour when daylight savings ends, without timezones because timezones
-are like character encodings - they're best applied only at the endpoints of an
-application (i.e. convert to UTC upon user input, re-apply desired timezone upon display).
+A function that works like "CURRENT_TIMESTAMP" except applies the
+appropriate conversions so that the time is in UTC time. Timestamps are best
+stored in relational databases as UTC, without time zones. UTC so that your
+database doesn't think time has gone backwards in the hour when daylight
+savings ends, without timezones because timezones are like character
+encodings - they're best applied only at the endpoints of an application
+(i.e. convert to UTC upon user input, re-apply desired timezone upon display).
For Postgresql and Microsoft SQL Server::
@@ -298,10 +311,10 @@ Example usage::
"GREATEST" function
-------------------
-The "GREATEST" function is given any number of arguments and returns the one that is
-of the highest value - it's equivalent to Python's ``max`` function. A SQL
-standard version versus a CASE based version which only accommodates two
-arguments::
+The "GREATEST" function is given any number of arguments and returns the one
+that is of the highest value - it's equivalent to Python's ``max``
+function. A SQL standard version versus a CASE based version which only
+accommodates two arguments::
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
@@ -339,7 +352,8 @@ Example usage::
"false" expression
------------------
-Render a "false" constant expression, rendering as "0" on platforms that don't have a "false" constant::
+Render a "false" constant expression, rendering as "0" on platforms that
+don't have a "false" constant::
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
@@ -370,6 +384,7 @@ Example usage::
from .. import exc
from ..sql import visitors
+
def compiles(class_, *specs):
"""Register a function as a compiler for a
given :class:`.ClauseElement` type."""
@@ -384,7 +399,8 @@ def compiles(class_, *specs):
existing.specs['default'] = existing_dispatch
# TODO: why is the lambda needed ?
- setattr(class_, '_compiler_dispatch', lambda *arg, **kw: existing(*arg, **kw))
+ setattr(class_, '_compiler_dispatch',
+ lambda *arg, **kw: existing(*arg, **kw))
setattr(class_, '_compiler_dispatcher', existing)
if specs:
@@ -396,6 +412,7 @@ def compiles(class_, *specs):
return fn
return decorate
+
def deregister(class_):
"""Remove all custom compilers associated with a given
:class:`.ClauseElement` type."""
@@ -422,4 +439,3 @@ class _dispatcher(object):
"%s construct has no default "
"compilation handler." % type(element))
return fn(element, compiler, **kw)
-