root / elixir / tags / 0.7.0 / elixir / ext / perform_ddl.py

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

apply patch from "Secator" to fix py2.6 warnings

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