root / elixir / trunk / elixir / ext / perform_ddl.py

Revision 502, 3.2 kB (checked in by ged, 3 years ago)

fix ReST markup so that API docs look good

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1'''
2DDL statements for Elixir.
3
4Entities having the perform_ddl statement, will automatically execute the
5given DDL statement, at the given moment: ether before or after the table
6creation in SQL.
7
8The 'when' argument can be either 'before-create' or 'after-create'.
9The 'statement' argument can be one of:
10
11- a single string statement
12- a list of string statements, in which case, each of them will be executed
13  in turn.
14- a callable which should take no argument and return either a single string
15  or a list of strings.
16
17In each string statement, you may use the special '%(fullname)s' construct,
18that will be replaced with the real table name including schema, if unknown
19to you. Also, self explained '%(table)s' and '%(schema)s' may be used here.
20
21You would use this extension to handle non elixir sql statemts, like triggers
22etc.
23
24.. sourcecode:: python
25
26    class Movie(Entity):
27        title = Field(Unicode(30), primary_key=True)
28        year = Field(Integer)
29
30        perform_ddl('after-create',
31                    "insert into %(fullname)s values ('Alien', 1979)")
32
33preload_data is a more specific statement meant to preload data in your
34entity table from a list of tuples (of fields values for each row).
35
36.. sourcecode:: python
37
38    class Movie(Entity):
39        title = Field(Unicode(30), primary_key=True)
40        year = Field(Integer)
41
42        preload_data(('title', 'year'),
43                     [(u'Alien', 1979), (u'Star Wars', 1977)])
44        preload_data(('year', 'title'),
45                     [(1982, u'Blade Runner')])
46        preload_data(data=[(u'Batman', 1966)])
47'''
48
49from elixir.statements import Statement
50from elixir.properties import EntityBuilder
51from sqlalchemy import DDL
52
53__all__ = ['perform_ddl', 'preload_data']
54__doc_all__ = []
55
56#
57# the perform_ddl statement
58#
59class PerformDDLEntityBuilder(EntityBuilder):
60
61    def __init__(self, entity, when, statement, on=None, context=None):
62        self.entity = entity
63        self.when = when
64        self.statement = statement
65        self.on = on
66        self.context = context
67
68    def after_table(self):
69        statement = self.statement
70        if hasattr(statement, '__call__'):
71            statement = statement()
72        if not isinstance(statement, list):
73            statement = [statement]
74        for s in statement:
75            ddl = DDL(s, self.on, self.context)
76            ddl.execute_at(self.when, self.entity.table)
77
78perform_ddl = Statement(PerformDDLEntityBuilder)
79
80#
81# the preload_data statement
82#
83class PreloadDataEntityBuilder(EntityBuilder):
84
85    def __init__(self, entity, columns=None, data=None):
86        self.entity = entity
87        self.columns = columns
88        self.data = data
89
90    def after_table(self):
91        all_columns = [col.name for col in self.entity.table.columns]
92        def onload(event, schema_item, connection):
93            columns = self.columns
94            if columns is None:
95                columns = all_columns
96            data = self.data
97            if hasattr(data, '__call__'):
98                data = data()
99            insert = schema_item.insert()
100            connection.execute(insert,
101                [dict(zip(columns, values)) for values in data])
102
103        self.entity.table.append_ddl_listener('after-create', onload)
104
105preload_data = Statement(PreloadDataEntityBuilder)
Note: See TracBrowser for help on using the browser.