Mercurial > eagle-eye
comparison ikweb/tools/lazygen_model.py @ 247:7747bbe5b68e
start to develope Information Exchange Center of Ikariam Game. (prototpye)
author | "Hisn Yi, Chen <ossug.hychen@gmail.com>" |
---|---|
date | Mon, 01 Dec 2008 00:27:22 +0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
246:60c4b4b78a01 | 247:7747bbe5b68e |
---|---|
1 #!/usr/bin/env python | |
2 import re | |
3 import os | |
4 import sys | |
5 | |
6 from sqlalchemy import * | |
7 # dirty import XD | |
8 gaeo_home = os.getenv('GAEO_HOME').replace('~',os.getenv('HOME'))+'/bin' | |
9 try: | |
10 sys.path.append(gaeo_home) | |
11 from gaeogen import * | |
12 except ImportError, e: | |
13 print "can not import gaeogen, the gaeogen path maybe wrong, got path:%s" % gaeo_home | |
14 sys.exit() | |
15 | |
16 | |
17 def sqlite_column_mapper(model_class, table_obj): | |
18 """ | |
19 map sqlite columns of the table to GAEO Model | |
20 | |
21 >>> metadata = MetaData() | |
22 >>> users_table = Table('users', metadata, | |
23 ... Column('id', Integer, primary_key=True), | |
24 ... Column('name', String), | |
25 ... Column('fullname', String), | |
26 ... Column('password', String) | |
27 ... ) | |
28 >>> model = sqlite_column_mapper(GenModel, users_table) | |
29 >>> model.generate_content() | |
30 """ | |
31 def convertor(col_type): | |
32 lowertype = col_type.lower() | |
33 | |
34 if re.match('char', lowertype): col_type = "String" | |
35 if re.match('(int|integer)', lowertype): col_type = 'Integer' | |
36 return col_type | |
37 | |
38 model = model_class(table_obj.name) | |
39 | |
40 for column in table_obj.columns: | |
41 model.add_property( "%s" % GenProperty(column.name, | |
42 column, | |
43 convertor)) | |
44 return model | |
45 | |
46 class GenProperty(object): | |
47 """ | |
48 GAE Property Generator. | |
49 | |
50 class Property(verbose_name=None, name=None, default=None, required=False, validator=None, choices=None) | |
51 """ | |
52 db_prefix = "^(SL|PG|Max|MS|FB|Ac|Info|Oracle)" | |
53 | |
54 def __init__(self, name, column=False, convertor=False): | |
55 """ | |
56 >>> col = Column('summary', String(2000)) | |
57 >>> p = GenProperty('summary', col) | |
58 >>> "%s" % p | |
59 "summary:StringProperty(verbose_name='summary',name='summary')" | |
60 >>> meta = MetaData() | |
61 >>> meta.bind = create_engine("sqlite:///dummy.sqlite") | |
62 >>> t = Table('ally', meta, autoload=True) | |
63 >>> p = GenProperty('name', t.columns.get('name')) | |
64 >>> "%s" % p | |
65 "name:TextProperty(verbose_name='name',name='name')" | |
66 >>> p = GenProperty('name', t.columns.get('time')) | |
67 >>> "%s" % p | |
68 "name:DatetimeProperty(verbose_name='name',name='name')" | |
69 """ | |
70 self.name = name | |
71 self.column = column | |
72 | |
73 # very dirty ... | |
74 if column: | |
75 self.type_name = re.sub( self.db_prefix,'', | |
76 column.type.__class__.__name__) | |
77 if convertor: | |
78 self.type_name = convertor(self.type_name) | |
79 | |
80 def __str__(self): | |
81 return self.gen() | |
82 | |
83 def gen(self): | |
84 """ | |
85 generate gaeo property code. | |
86 """ | |
87 clause= self.create_clause(self.type_name, self.column) | |
88 return gae_property_code(self.name, self.type_name, clause) | |
89 | |
90 def create_clause(self, type, column): | |
91 """ | |
92 create property cluase. | |
93 | |
94 >>> s = Column('summary', String(2000)) | |
95 >>> code = GenProperty(s.name).create_clause('string', s) | |
96 >>> code | |
97 {'verbose_name': 'summary', 'name': 'summary'} | |
98 """ | |
99 clause= self.create_basic_clause(column) | |
100 | |
101 try: | |
102 other_caluse = getattr(self, 'create_%s_clause' % type.lower())(column) | |
103 clause.update(other_caluse) | |
104 except: | |
105 pass | |
106 | |
107 return clause | |
108 | |
109 def create_basic_clause(self, column): | |
110 """ | |
111 create basic property cluase. | |
112 """ | |
113 clause = {'verbose_name':self.name, 'name':self.name} | |
114 | |
115 if column.default: | |
116 clause.setdefault('default', column.default) | |
117 elif column.server_default: | |
118 clause.setdefault('default', column.server_default) | |
119 | |
120 return clause | |
121 | |
122 def gae_property_code(name, type, clause): | |
123 """ | |
124 generate google app engine property code. | |
125 | |
126 >>> gae_property_code('name', 'string', {'default':'hychen','name':'hi'}) | |
127 "name:StringProperty(default='hychen',name='hi')" | |
128 """ | |
129 argv = [] | |
130 | |
131 def _quote(v): | |
132 try: | |
133 return "'"+v+"'" | |
134 except TypeError: | |
135 pass | |
136 | |
137 for k,v in clause.items(): | |
138 argv.append("%s=%s" % (k, _quote(v) ) ) | |
139 | |
140 return "%s:%sProperty(%s)" % (name, | |
141 type.capitalize(), | |
142 ','.join(argv)) | |
143 | |
144 class ModelMaker: | |
145 | |
146 is_build = False | |
147 | |
148 def __init__(self, **kwds): | |
149 """ | |
150 to create GAEO Model | |
151 | |
152 >>> maker = ModelMaker(schema="sqlite:///dummy.sqlite", autoload=True) | |
153 >>> maker.build() | |
154 """ | |
155 self.models = [] | |
156 self.set_engine(kwds['schema']) | |
157 | |
158 try: | |
159 if True == kwds['autoload']: | |
160 self.table_names = self.db_engine.table_names() | |
161 else: | |
162 self.table_names = kwds['include_tables'] | |
163 except KeyError: | |
164 print "input wrong argv." | |
165 | |
166 def set_engine(self, schema): | |
167 """ | |
168 set db engine | |
169 """ | |
170 self.db_engine = create_engine(schema) | |
171 self.meta = MetaData() | |
172 self.meta.bind = self.db_engine | |
173 | |
174 def build(self): | |
175 """ | |
176 build models by talbse in database. | |
177 """ | |
178 mapper_func = '%s_column_mapper' % self.db_engine.name.lower() | |
179 | |
180 for table_name in self.table_names: | |
181 table = Table(table_name, self.meta, autoload=True) | |
182 self.models.append( eval(mapper_func)( GenModel, table) ) | |
183 | |
184 self.is_build = True | |
185 | |
186 def save(self): | |
187 """ | |
188 save model | |
189 """ | |
190 if self.is_build: | |
191 application_dir = os.path.join(os.getcwd(), 'application') | |
192 model_dir = os.path.join(application_dir, 'model') | |
193 | |
194 # check if the model directory had been created | |
195 if not os.path.exists(os.path.join(model_dir, '__init__.py')): | |
196 create_file(os.path.join(model_dir, '__init__.py'), []) | |
197 | |
198 for model in self.models: | |
199 print 'Creating Model %s ...' % model.name | |
200 model.save(os.path.join(model_dir, '%s.py' % model.name)) | |
201 else: | |
202 print "not build yet." | |
203 | |
204 def gen_models_from_db(db_schema, include_tables=False): | |
205 """ | |
206 generate models form database. | |
207 | |
208 gen_models_from_db("sqlite://dumy.sqlite") | |
209 | |
210 # spefiy tables | |
211 gen_models_from_db("sqlite://dumy.sqlite", include_tables=['tb1','tb2']) | |
212 """ | |
213 if not include_tables: | |
214 maker = ModelMaker(schema=db_schema, autoload=True) | |
215 else: | |
216 maker = ModelMaker(schema=db_schema, include_tables=include_tables) | |
217 | |
218 maker.build() | |
219 maker.save() | |
220 | |
221 if '__main__' == __name__: | |
222 import sys | |
223 | |
224 if 'test' == sys.argv[1]: | |
225 import doctest | |
226 doctest.testmod() | |
227 else: | |
228 gen_models_from_db(sys.argv[1]) |