root/galaxy-central/eggs/SQLAlchemy-0.5.6_dev_r6498-py2.6.egg/sqlalchemy/ext/compiler.py @ 3

リビジョン 3, 3.6 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1"""Provides an API for creation of custom ClauseElements and compilers.
2
3Synopsis
4========
5
6Usage involves the creation of one or more :class:`~sqlalchemy.sql.expression.ClauseElement`
7subclasses and one or more callables defining its compilation::
8
9    from sqlalchemy.ext.compiler import compiles
10    from sqlalchemy.sql.expression import ColumnClause
11   
12    class MyColumn(ColumnClause):
13        pass
14           
15    @compiles(MyColumn)
16    def compile_mycolumn(element, compiler, **kw):
17        return "[%s]" % element.name
18       
19Above, ``MyColumn`` extends :class:`~sqlalchemy.sql.expression.ColumnClause`, the
20base expression element for column objects.  The ``compiles`` decorator registers
21itself with the ``MyColumn`` class so that it is invoked when the object
22is compiled to a string::
23
24    from sqlalchemy import select
25   
26    s = select([MyColumn('x'), MyColumn('y')])
27    print str(s)
28   
29Produces::
30
31    SELECT [x], [y]
32
33Compilers can also be made dialect-specific.  The appropriate compiler will be invoked
34for the dialect in use::
35
36    from sqlalchemy.schema import DDLElement  # this is a SQLA 0.6 construct
37
38    class AlterColumn(DDLElement):
39
40        def __init__(self, column, cmd):
41            self.column = column
42            self.cmd = cmd
43
44    @compiles(AlterColumn)
45    def visit_alter_column(element, compiler, **kw):
46        return "ALTER COLUMN %s ..." % element.column.name
47
48    @compiles(AlterColumn, 'postgres')
49    def visit_alter_column(element, compiler, **kw):
50        return "ALTER TABLE %s ALTER COLUMN %s ..." % (element.table.name, element.column.name)
51
52The second ``visit_alter_table`` will be invoked when any ``postgres`` dialect is used.
53
54The ``compiler`` argument is the :class:`~sqlalchemy.engine.base.Compiled` object
55in use.  This object can be inspected for any information about the in-progress
56compilation, including ``compiler.dialect``, ``compiler.statement`` etc.
57The :class:`~sqlalchemy.sql.compiler.SQLCompiler` and :class:`~sqlalchemy.sql.compiler.DDLCompiler` (DDLCompiler is 0.6. only)
58both include a ``process()`` method which can be used for compilation of embedded attributes::
59
60    class InsertFromSelect(ClauseElement):
61        def __init__(self, table, select):
62            self.table = table
63            self.select = select
64
65    @compiles(InsertFromSelect)
66    def visit_insert_from_select(element, compiler, **kw):
67        return "INSERT INTO %s (%s)" % (
68            compiler.process(element.table, asfrom=True),
69            compiler.process(element.select)
70        )
71
72    insert = InsertFromSelect(t1, select([t1]).where(t1.c.x>5))
73    print insert
74   
75Produces::
76
77    "INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z FROM mytable WHERE mytable.x > :x_1)"
78
79
80"""
81
82def compiles(class_, *specs):
83    def decorate(fn):
84        existing = getattr(class_, '_compiler_dispatcher', None)
85        if not existing:
86            existing = _dispatcher()
87
88            # TODO: why is the lambda needed ?
89            setattr(class_, '_compiler_dispatch', lambda *arg, **kw: existing(*arg, **kw))
90            setattr(class_, '_compiler_dispatcher', existing)
91       
92        if specs:
93            for s in specs:
94                existing.specs[s] = fn
95        else:
96            existing.specs['default'] = fn
97        return fn
98    return decorate
99   
100class _dispatcher(object):
101    def __init__(self):
102        self.specs = {}
103   
104    def __call__(self, element, compiler, **kw):
105        # TODO: yes, this could also switch off of DBAPI in use.
106        fn = self.specs.get(compiler.dialect.name, None)
107        if not fn:
108            fn = self.specs['default']
109        return fn(element, compiler, **kw)
110       
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。