Mercurial > eagle-eye
view 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 |
line wrap: on
line source
#!/usr/bin/env python import re import os import sys from sqlalchemy import * # dirty import XD gaeo_home = os.getenv('GAEO_HOME').replace('~',os.getenv('HOME'))+'/bin' try: sys.path.append(gaeo_home) from gaeogen import * except ImportError, e: print "can not import gaeogen, the gaeogen path maybe wrong, got path:%s" % gaeo_home sys.exit() def sqlite_column_mapper(model_class, table_obj): """ map sqlite columns of the table to GAEO Model >>> metadata = MetaData() >>> users_table = Table('users', metadata, ... Column('id', Integer, primary_key=True), ... Column('name', String), ... Column('fullname', String), ... Column('password', String) ... ) >>> model = sqlite_column_mapper(GenModel, users_table) >>> model.generate_content() """ def convertor(col_type): lowertype = col_type.lower() if re.match('char', lowertype): col_type = "String" if re.match('(int|integer)', lowertype): col_type = 'Integer' return col_type model = model_class(table_obj.name) for column in table_obj.columns: model.add_property( "%s" % GenProperty(column.name, column, convertor)) return model class GenProperty(object): """ GAE Property Generator. class Property(verbose_name=None, name=None, default=None, required=False, validator=None, choices=None) """ db_prefix = "^(SL|PG|Max|MS|FB|Ac|Info|Oracle)" def __init__(self, name, column=False, convertor=False): """ >>> col = Column('summary', String(2000)) >>> p = GenProperty('summary', col) >>> "%s" % p "summary:StringProperty(verbose_name='summary',name='summary')" >>> meta = MetaData() >>> meta.bind = create_engine("sqlite:///dummy.sqlite") >>> t = Table('ally', meta, autoload=True) >>> p = GenProperty('name', t.columns.get('name')) >>> "%s" % p "name:TextProperty(verbose_name='name',name='name')" >>> p = GenProperty('name', t.columns.get('time')) >>> "%s" % p "name:DatetimeProperty(verbose_name='name',name='name')" """ self.name = name self.column = column # very dirty ... if column: self.type_name = re.sub( self.db_prefix,'', column.type.__class__.__name__) if convertor: self.type_name = convertor(self.type_name) def __str__(self): return self.gen() def gen(self): """ generate gaeo property code. """ clause= self.create_clause(self.type_name, self.column) return gae_property_code(self.name, self.type_name, clause) def create_clause(self, type, column): """ create property cluase. >>> s = Column('summary', String(2000)) >>> code = GenProperty(s.name).create_clause('string', s) >>> code {'verbose_name': 'summary', 'name': 'summary'} """ clause= self.create_basic_clause(column) try: other_caluse = getattr(self, 'create_%s_clause' % type.lower())(column) clause.update(other_caluse) except: pass return clause def create_basic_clause(self, column): """ create basic property cluase. """ clause = {'verbose_name':self.name, 'name':self.name} if column.default: clause.setdefault('default', column.default) elif column.server_default: clause.setdefault('default', column.server_default) return clause def gae_property_code(name, type, clause): """ generate google app engine property code. >>> gae_property_code('name', 'string', {'default':'hychen','name':'hi'}) "name:StringProperty(default='hychen',name='hi')" """ argv = [] def _quote(v): try: return "'"+v+"'" except TypeError: pass for k,v in clause.items(): argv.append("%s=%s" % (k, _quote(v) ) ) return "%s:%sProperty(%s)" % (name, type.capitalize(), ','.join(argv)) class ModelMaker: is_build = False def __init__(self, **kwds): """ to create GAEO Model >>> maker = ModelMaker(schema="sqlite:///dummy.sqlite", autoload=True) >>> maker.build() """ self.models = [] self.set_engine(kwds['schema']) try: if True == kwds['autoload']: self.table_names = self.db_engine.table_names() else: self.table_names = kwds['include_tables'] except KeyError: print "input wrong argv." def set_engine(self, schema): """ set db engine """ self.db_engine = create_engine(schema) self.meta = MetaData() self.meta.bind = self.db_engine def build(self): """ build models by talbse in database. """ mapper_func = '%s_column_mapper' % self.db_engine.name.lower() for table_name in self.table_names: table = Table(table_name, self.meta, autoload=True) self.models.append( eval(mapper_func)( GenModel, table) ) self.is_build = True def save(self): """ save model """ if self.is_build: application_dir = os.path.join(os.getcwd(), 'application') model_dir = os.path.join(application_dir, 'model') # check if the model directory had been created if not os.path.exists(os.path.join(model_dir, '__init__.py')): create_file(os.path.join(model_dir, '__init__.py'), []) for model in self.models: print 'Creating Model %s ...' % model.name model.save(os.path.join(model_dir, '%s.py' % model.name)) else: print "not build yet." def gen_models_from_db(db_schema, include_tables=False): """ generate models form database. gen_models_from_db("sqlite://dumy.sqlite") # spefiy tables gen_models_from_db("sqlite://dumy.sqlite", include_tables=['tb1','tb2']) """ if not include_tables: maker = ModelMaker(schema=db_schema, autoload=True) else: maker = ModelMaker(schema=db_schema, include_tables=include_tables) maker.build() maker.save() if '__main__' == __name__: import sys if 'test' == sys.argv[1]: import doctest doctest.testmod() else: gen_models_from_db(sys.argv[1])