Exemple #1
0
    def perform(self, args):
        opts=self.parse_args(args)
        try:
            _schema=Schema('config/schema.yaml')
            _schema.fix_tables()
        except TypeError:
            print red('The schema is not defined.')
            sys.exit(-1)
        gen=Generator(opts['verbose'])
        for model_name in _schema.get_tables_list():
            print '\n'+bold('Generating {0} model...'.format(model_name))
            templates=gen.create_b(model_name, _schema.find_table(model_name))
            if opts['dump']:
                print '\napplication/model/base/{0}Base.py'.format(
                    templates['base'][0])
                print templates['base'][1]
                if templates.get('rel')!=None:
                    for rel in templates['rel']:
                        print '\n\napplication/model/relation/{0}.py'.format(
                            rel[0])
                        print rel[1]
            else :
                gen.write_base_model(templates['base'][0],
                    templates['base'][1])
                if templates.get('rel')!=None:
                    for rel in templates['rel']:
                        gen.write_relation(rel[0], rel[1])

            print bold('Model {0} created successfully.'.format(model_name))
Exemple #2
0
    def perform(self, args):
        model_name, opts = self.parse_args(args)
        try:
            _schema = Schema('config/schema.yaml')
            _schema.fix_tables()
        except TypeError:
            print red('The schema is not defined.')
            sys.exit(-1)
        if not check_model(model_name):
            print red('\n{0} model does not exist at the project schema.\n' \
            'Use model -l or model --list to show a list of available models.'\
            .format(model_name if len(model_name) else 'Noname'))
            sys.exit(0)
        print '\n' + bold('Generating {0} model...'.format(model_name))
        gen = Generator(opts['verbose'])
        templates = gen.create_b(model_name, _schema.find_table(model_name))
        if opts['dump']:
            print '\napplication/model/base/{0}Base.py'.format(
                templates['base'][0])
            print templates['base'][1]
            if templates.get('rel') != None:
                for rel in templates['rel']:
                    print '\n\napplication/model/relation/{0}.py'.format(
                        rel[0])
                    print rel[1]
        else:
            gen.write_base_model(templates['base'][0], templates['base'][1])
            if templates.get('rel') != None:
                for rel in templates['rel']:
                    gen.write_relation(rel[0], rel[1])

        print bold('Model created successfully.')
Exemple #3
0
    def perform(self, args):
        model_name, opts=self.parse_args(args)
        try:
            _schema=Schema('config/schema.yaml')
            _schema.fix_tables()
        except TypeError:
            print red('The schema is not defined.')
            sys.exit(-1)
        if not check_model(model_name):
            print red('\n{0} model does not exist at the project schema.\n' \
            'Use model -l or model --list to show a list of available models.'\
            .format(model_name if len(model_name) else 'Noname'))
            sys.exit(0)
        print '\n'+bold('Generating {0} model...'.format(model_name))
        gen=Generator(opts['verbose'])
        templates=gen.create_b(model_name, _schema.find_table(model_name))
        if opts['dump']:
            print '\napplication/model/base/{0}Base.py'.format(
                templates['base'][0])
            print templates['base'][1]
            if templates.get('rel')!=None:
                for rel in templates['rel']:
                    print '\n\napplication/model/relation/{0}.py'.format(
                        rel[0])
                    print rel[1]
        else :
            gen.write_base_model(templates['base'][0], templates['base'][1])
            if templates.get('rel')!=None:
                for rel in templates['rel']:
                    gen.write_relation(rel[0], rel[1])

        print bold('Model created successfully.')
Exemple #4
0
def model_list():
    """Return a list of available models at current schema"""
    try:
        _schema = Schema('config/schema.yaml')
        for table in _schema.get_tables_list():
            print brown(table)
    except TypeError:
        print red('Schema is not defined.')
Exemple #5
0
 def __init__(self, verbose=False):
     self._verbose = verbose
     self._schema = Schema('config/schema.yaml')
     if self._verbose: print bold('Fixing null values on schema...')
     (success, msg) = self._schema.fix_tables()
     if not success:
         raise SchemaException(msg)
     if self._verbose: print green('Schema fixed!')
Exemple #6
0
def model_list():
    """Return a list of available models at current schema"""
    try:
        _schema=Schema('config/schema.yaml')
        for table in _schema.get_tables_list():
            print brown(table)
    except TypeError:
        print red('Schema is not defined.')
Exemple #7
0
def check_model(model_name):
    """Checks if a model given by model name exists at the current schema"""
    if not len(model_name):
        return False

    _schema=Schema('config/schema.yaml')
    if not model_name in _schema.get_tables_list():
        return False

    return True
Exemple #8
0
def check_model(model_name):
    """Checks if a model given by model name exists at the current schema"""
    if not len(model_name):
        return False

    _schema = Schema('config/schema.yaml')
    if not model_name in _schema.get_tables_list():
        return False

    return True
Exemple #9
0
    def __init__(self):
        super(Database, self).__init__()

        self._schema = Schema('config/schema.yaml')
        try:
            self._db = create_database(self._schema.get_properties()['uri'])
            self._initialized = True
        except:
            self._initialized = False
            raise DatabaseException("Database schema is not defined")
Exemple #10
0
class Database(Borg):
    _db = None
    _conn = None
    _schema = None
    _fixed = False

    def __init__(self):
        super(Database, self).__init__()

        self._schema = Schema('config/schema.yaml')
        try:
            self._db = create_database(self._schema.get_properties()['uri'])
            self._initialized = True
        except:
            self._initialized = False
            raise DatabaseException("Database schema is not defined")

    def is_valid(self):
        return self._initialized

    def get_database(self):
        return self._db

    def get_schema(self):
        if not self._schema.is_fixed():
            self._schema.fix_tables()
        return self._schema

    def get_connection(self):
        if self._conn == None:
            self.connect()
        return self._conn

    def connect(self):
        if self._conn == None:
            self._conn = self._db.connect()

    def query(self, data):
        self._conn.execute(data)
        self._conn.commit()

    def create(self, script):
        drop = script.split('\n')[0]
        create = ''.join(script.split('\n')[2:])
        try:
            self._conn.execute(drop)
        except ProgrammingError, e:
            print 'Drop fail: ', e[0]
            self._conn.commit()
        except OperationalError, e:
            print 'Drop fail: ', e[0]
            self._conn.commit()
Exemple #11
0
class Database(Borg):
    _db=None
    _conn=None
    _schema=None
    _fixed=False

    def __init__(self):
        super(Database, self).__init__()

        self._schema=Schema('config/schema.yaml')
        try:
            self._db=create_database(self._schema.get_properties()['uri'])
            self._initialized=True
        except:
            self._initialized=False
            raise DatabaseException("Database schema is not defined")

    def is_valid(self):
        return self._initialized

    def get_database(self):
        return self._db

    def get_schema(self):
        if not self._schema.is_fixed():
            self._schema.fix_tables()
        return self._schema

    def get_connection(self):
        if self._conn==None:
            self.connect()
        return self._conn

    def connect(self):
        if self._conn==None:
            self._conn=self._db.connect()

    def query(self, data):
        self._conn.execute(data)
        self._conn.commit()

    def create(self, script):
        drop=script.split('\n')[0]
        create=''.join(script.split('\n')[2:])
        try:
            self._conn.execute(drop)
        except ProgrammingError, e:
            print 'Drop fail: ', e[0]
            self._conn.commit()
        except OperationalError, e:
            print 'Drop fail: ', e[0]
            self._conn.commit()
Exemple #12
0
 def __init__(self, verbose=False):
     self._verbose=verbose
     self._schema=Schema('config/schema.yaml')
     if self._verbose: print bold('Fixing null values on schema...')
     (success, msg)=self._schema.fix_tables()
     if not success:
         raise SchemaException(msg)
     if self._verbose: print green('Schema fixed!')
Exemple #13
0
    def __init__(self):
        super(Database, self).__init__()

        self._schema=Schema('config/schema.yaml')
        try:
            self._db=create_database(self._schema.get_properties()['uri'])
            self._initialized=True
        except:
            self._initialized=False
            raise DatabaseException("Database schema is not defined")
Exemple #14
0
    def perform(self, args):
        opts = self.parse_args(args)
        try:
            _schema = Schema('config/schema.yaml')
            _schema.fix_tables()
        except TypeError:
            print red('The schema is not defined.')
            sys.exit(-1)
        gen = Generator(opts['verbose'])
        for model_name in _schema.get_tables_list():
            print '\n' + bold('Generating {0} model...'.format(model_name))
            templates = gen.create_b(model_name,
                                     _schema.find_table(model_name))
            if opts['dump']:
                print '\napplication/model/base/{0}Base.py'.format(
                    templates['base'][0])
                print templates['base'][1]
                if templates.get('rel') != None:
                    for rel in templates['rel']:
                        print '\n\napplication/model/relation/{0}.py'.format(
                            rel[0])
                        print rel[1]
            else:
                gen.write_base_model(templates['base'][0],
                                     templates['base'][1])
                if templates.get('rel') != None:
                    for rel in templates['rel']:
                        gen.write_relation(rel[0], rel[1])

            print bold('Model {0} created successfully.'.format(model_name))
Exemple #15
0
class Generator(object):
    _schema = None
    _mgr = TemplateManager()

    def __init__(self, verbose=False):
        self._verbose = verbose
        self._schema = Schema('config/schema.yaml')
        if self._verbose: print bold('Fixing null values on schema...')
        (success, msg) = self._schema.fix_tables()
        if not success:
            raise SchemaException(msg)
        if self._verbose: print green('Schema fixed!')

    def generate_models(self):
        for table, columns in self._schema.get_tables().iteritems():
            mod_name, tpl = self.generate_model_base(table, columns)
            self.write_base_model(mod_name, tpl)
            mod_name, tpl = self.generate_model(table, columns)
            self.write_model(mod_name, tpl)

    def create_b(self, table, columns):
        templates = {
            'base': self.generate_model_base(table, columns),
            'rel': self.generate_many_2_many(table, columns)
        }

        return templates

    def create_m(self, table, columns, path):
        return {'work': self.generate_model(table, columns, path)}

    def generate_model(self, table, columns, path):
        t = self._mgr.get_sys_domain().get_template('tpl/model.evoque')
        model_name = self._generate_model_name(table)
        return (model_name,
                t.evoque(
                    model_name=model_name,
                    module_register_path=path,
                    model_creation_date=datetime.now(),
                    model_file='application/model/{0}'.format(model_name),
                ))

    def generate_model_base(self, table, columns):
        t = self._mgr.get_sys_domain().get_template('tpl/modelbase.evoque')
        relation = columns.get('_relation')
        model_name = self._generate_model_name(table)
        _attributes = []
        _relations = []
        _model_primary_keys = self._check_composed_keys(columns)
        cfg = config.ConfigManager().look_at_cur_path()
        if cfg == None:
            print red('No goliat configuration file found.')
            sys.exit(-1)
        for col in self._schema.reorder_table_fields(
                self._schema.find_table(table)):
            if col[0] in [
                    '_config', '_indexes', '_relation', '_order', '_parent'
            ]:
                continue
            attr_name = col[0]
            if len(_model_primary_keys):
                attr_type = self._parse_column(col[1], True)
            else:
                attr_type = self._parse_column(col[1])

            _attributes.append((attr_name, attr_type))
        if relation != None:
            for field, rel in relation.iteritems():
                if rel['type'] == 'one2one':
                    _reference = 'Reference'
                    _attributes.append((field, '{0}({1}_id, "{2}.{3}")' \
                        .format(_reference, field, self._generate_model_name(\
                        rel['foreignTable']), rel['foreignKey'])))
                    _relations.append(('application.model.base.{0}Base' \
                        .format(self._generate_model_name(
                            rel['foreignTable'])),
                            '{0}Base'.format(self._generate_model_name(
                                rel['foreignTable']))))
                elif rel['type'] == 'many2one':
                    _reference = 'ReferenceSet'
                    _attributes.append(
                        (field,
                         '{0}'.format('{0}("{1}.{2}", "{3}.{4}")'.format(
                             _reference, self._generate_model_name(table),
                             rel['localKey'],
                             self._generate_model_name(rel['foreignTable']),
                             rel['foreignKey']))))
                    _relations.append(('application.model.base.{0}Base' \
                    .format(self._generate_model_name(rel['foreignTable'])),
                        '{0}Base'.format(self._generate_model_name(
                            rel['foreignTable']))))
                elif rel['type'] == 'many2many':
                    _reference = 'ReferenceSet'
                    reference = _reference + '('
                    reference += self._parse_relation(rel, table)
                    reference += ')'
                    _attributes.append(('{0}'.format(field), reference))
                    #_relations.append(('application.model.base.{0}Base' \
                    #.format(self._generate_model_name(rel['foreignTable'])),
                    #    '{0}Base'.format(self._generate_model_name(
                    #        rel['foreignTable']))))
                    _relations.append((
                        'application.model.relation.{0}'.format(
                            self._generate_model_name(table)+\
                            self._generate_model_name(rel['foreignTable'])),
                        self._generate_model_name(table)+\
                        self._generate_model_name(rel['foreignTable'])
                    ))

        reverse = self._schema.find_reverse_reference(table)
        if reverse != None:
            reverse_reference = 'ReferenceSet('
            reverse_reference += self._parse_relation(reverse, table, True)
            reverse_reference += ')'
            _attributes.append(
                ('{0}'.format(reverse['field']), reverse_reference))
            _relations.append((
                'application.model.relation.{0}'.format(
                    self._generate_model_name(reverse['foreignTable'])+\
                    self._generate_model_name(table)),
                self._generate_model_name(reverse['foreignTable'])+\
                self._generate_model_name(table)
            ))

        return (model_name,
                t.evoque(
                    model_name=model_name,
                    model_creation_date=datetime.now(),
                    model_file='application/model/base/{0}'.format(model_name),
                    model_table='{0}'.format(table),
                    model_primary_keys=_model_primary_keys,
                    attributes=_attributes,
                    relations=_relations))

    def generate_many_2_many(self, table, columns):
        if columns.get('_relation') == None:
            return None

        models = []
        for field, relation in columns['_relation'].iteritems():
            if not self._analyze(relation):
                raise SchemaException('%s table has an invalid _relation ' \
                    'section, please fix it!!!'%(table))
            if relation['type'] != 'many2many':
                continue  # Not a m2m relationship

            t=self._mgr.get_sys_domain().get_template(\
                'tpl/modelrelation.evoque')
            modelSuffix=''.join([ word.capitalize() \
                    for word in table.split('_') ])
            modelPreffix=''.join([ word.capitalize() \
                    for word in relation['foreignTable'].split('_') ])
            model_name = modelSuffix + modelPreffix
            _model_primary_keys = self._generate_primary_keys(relation['keys'])
            _attributes = []
            for key in relation['keys']:
                attr_name = key if type(key) == str else key.keys()[0]
                attr_type = 'Int()'
                _attributes.append((attr_name, attr_type))
            if relation.get('fields') != None:
                for field in relation['fields']:
                    for fname, fvalue in field.iteritems():
                        attr_name = fname
                        attr_type = self._parse_column(fvalue, True)
                        _attributes.append((attr_name, attr_type))

            models.append(
                (model_name,
                 t.evoque(model_name=model_name,
                          model_creation_date=datetime.now(),
                          model_file='application/model/relation/{0}'.format(
                              model_name),
                          model_table='{0}'.format(table + '_' +
                                                   relation['foreignTable']),
                          model_primary_keys=_model_primary_keys,
                          attributes=_attributes)))

        return models

    def write_base_model(self, mod_name, tpl):
        fp = file('application/model/base/{0}Base.py'.format(mod_name), 'w')
        fp.write(tpl.encode('utf8'))
        fp.close()

    def write_model(self, mod_name, tpl):
        fp = file('application/model/{0}.py'.format(mod_name), 'w')
        fp.write(tpl.encode('utf8'))
        fp.close()

    def write_relation(self, mod_name, tpl):
        fp = file('application/model/relation/{0}.py'.format(mod_name), 'w')
        fp.write(tpl.encode('utf8'))
        fp.close()

    def _generate_model_name(self, table):
        return ''.join([word.capitalize() for word in table.split('_')])

    def _check_composed_keys(self, cols):
        keys = []
        for name, col in cols.iteritems():
            if col in ['_relation', '_config', '_indexes']: continue
            if 'primaryKey' in col:
                keys.append(name)
        if len(keys) > 1:
            return self._generate_primary_keys(keys)

        return ''

    def _generate_primary_keys(self, keys):
        _new_keys = []
        for key in keys:
            if type(key) == str: _new_keys.append(key)
            elif type(key) == dict: _new_keys.append(key.keys()[0])

        return '__storm_primary__ = '+','.join([ '"'+k+'"' \
                for k in _new_keys ])

    def _analyze(self, config):
        """Analyzes a table _config section"""
        if config.get('type') == None or config.get('foreignTable') == None:
            return False

        return True

    def _parse_column(self, col, special=False):
        _primary = 'False'
        _allow_none = 'True'
        _default_value = 'Undef'
        _foreign_keys = False
        if col.get('type') != None:
            if col.get('primaryKey') != None and col.get('primaryKey') == True:
                _primary = 'True'
            if col.get('required') != None and col.get('required') == True:
                _allow_none = 'False'
            if col.get('default') != None:
                _default_value = col.get('default')

            if not special:
                return '{0}(primary={1}, value={2}, allow_none={3})' \
            .format(tr(col.get('type')), _primary, _default_value, _allow_none)
            else:
                return '{0}(value={1}, allow_none={2})' \
            .format(tr(col.get('type')), _default_value, _allow_none)

    def _parse_relation(self, rel, table, reverse=False):
        """Parses a model table relation."""
        _new_keys = []
        for key in rel['keys']:
            if type(key) == str:
                _new_keys.append(key)
            elif type(key) == dict:
                _new_keys.append(key.keys()[0])

        if not reverse:
            ret = '"{0}.{1}", '.format(self._generate_model_name(table),
                                       rel['localKey'])
            ret+='"{0}.{1}", '.format(self._generate_model_name(table)+\
                self._generate_model_name(rel['foreignTable']), _new_keys[0])
            ret+='"{0}.{1}", '.format(self._generate_model_name(table)+\
                self._generate_model_name(rel['foreignTable']), _new_keys[1])
            ret += '"{0}.{1}"'.format(
                self._generate_model_name(rel['foreignTable']),
                rel['foreignKey'])
        else:
            ret = '"{0}.{1}", '.format(self._generate_model_name(table),
                                       rel['localKey'])
            ret += '"{0}.{1}", '.format(
                self._generate_model_name(rel['foreignTable']) +
                self._generate_model_name(table), _new_keys[0])
            ret+='"{0}.{1}", '.format(self._generate_model_name(
                rel['foreignTable'])+\
                self._generate_model_name(table), _new_keys[1])
            ret += '"{0}.{1}"'.format(
                self._generate_model_name(rel['foreignTable']),
                rel['foreignKey'])

        return ret
Exemple #16
0
    def perform(self, args):
        cfg=self._look_at_cur_path()
        module_name, opts=self.parse_args(args)
        if not len(module_name):
            print self.long_help()
            sys.exit(-1)
        try:
            _schema=Schema('config/schema.yaml')
            _schema.fix_tables()
        except TypeError:
            if opts.get('model')!=None:
                print red('The schema is not defined.')
                sys.exit(-1)
        _module_model_import=''
        _module_get_schema_model=''

        if opts.get('path')==None:
            _module_register_path='"{0}"'.format(module_name.lower())
        else:
            _module_register_path='"{0}"'.format(opts['path'])
        if opts.get('model')!=None:
            if not check_model(opts['model']):
                print red(\
                '\n{0} model does not exist at the project schema.\nUse ' \
                'module -l or module --list to show a list of available ' \
                'models.'.format(\
                    opts['model'] if len(opts['model']) else 'Noname'))
                sys.exit(0)
            gen=Generator(opts['verbose'])
            _use_model=True
            _model_name=gen._generate_model_name(opts['model'])
            tmodel=gen.create_m(\
                opts['model'], _schema.find_table(opts['model']),
                _module_register_path)

            _module_model_import='from application.model.{0} import {1}' \
            .format(gen._generate_model_name(opts['model']),
                gen._generate_model_name(opts['model']))
            _module_get_schema_model='''def get_schema_model(self, request, **kwargs): 
        """Return the schema model %s architecture.""" 
        model_schema, model_view = %s.get_model_info() 
        if model_schema == None: 
            return json.dumps({
                "success" : False,
                "error" : "Unable to fetch a schema for model %s"
            })        
                
        return json.dumps({
            "success" : True,
            "model" : model_schema,
            "view" : model_view
        })'''%(gen._generate_model_name(opts['model']),
            gen._generate_model_name(opts['model']),
            opts['model'])

        print '\n'+bold('Generating {0} module...'.format(module_name))
        mgr=TemplateManager()
        t=mgr.get_sys_domain().get_template('tpl/module.evoque')
        module=t.evoque(
            module_file="application/controller/{0}".format(module_name),
            module_creation_date=datetime.now(),
            module_name=module_name,
            module_model_import=_module_model_import,
            module_register_path=_module_register_path,
            module_get_schema_model=_module_get_schema_model,
            use_model=_use_model,
            model_name=_model_name
        )
        if opts['dump']:
            if opts.get('model')!=None:
                print '\napplication/model/{0}.py'.format(tmodel['work'][0])
                print tmodel['work'][1]
            print '\napplication/controller/{0}.py'.format(module_name)
            print  module
        else :
            if opts.get('model')!=None:
                gen.write_model(tmodel['work'][0], tmodel['work'][1])
            fp=file('application/controller/{0}.py'.format(module_name), 'w')
            fp.write(module.encode('utf8'))
            fp.close()

        print bold('Module created successfully.')
Exemple #17
0
class Generator(object):
    _schema=None
    _mgr=TemplateManager()

    def __init__(self, verbose=False):
        self._verbose=verbose
        self._schema=Schema('config/schema.yaml')
        if self._verbose: print bold('Fixing null values on schema...')
        (success, msg)=self._schema.fix_tables()
        if not success:
            raise SchemaException(msg)
        if self._verbose: print green('Schema fixed!')

    def generate_models(self):
        for table, columns in self._schema.get_tables().iteritems():
            mod_name, tpl=self.generate_model_base(table, columns)
            self.write_base_model(mod_name, tpl)
            mod_name, tpl=self.generate_model(table, columns)
            self.write_model(mod_name, tpl)

    def create_b(self, table, columns):
        templates={
            'base'  : self.generate_model_base(table, columns),
            'rel'   : self.generate_many_2_many(table, columns)
        }

        return templates

    def create_m(self, table, columns, path):
        return {
            'work'  : self.generate_model(table, columns, path)
        }

    def generate_model(self, table, columns, path):
        t=self._mgr.get_sys_domain().get_template('tpl/model.evoque')
        model_name=self._generate_model_name(table)
        return (model_name, t.evoque(
            model_name=model_name,
            module_register_path=path,
            model_creation_date=datetime.now(),
            model_file='application/model/{0}'.format(model_name),
        ))

    def generate_model_base(self, table, columns):
        t=self._mgr.get_sys_domain().get_template('tpl/modelbase.evoque')
        relation=columns.get('_relation')
        model_name=self._generate_model_name(table)
        _attributes=[]
        _relations=[]
        _model_primary_keys=self._check_composed_keys(columns)
        cfg=config.ConfigManager().look_at_cur_path()
        if cfg==None:
            print red('No goliat configuration file found.')
            sys.exit(-1)
        for col in self._schema.reorder_table_fields(
                self._schema.find_table(table)):
            if col[0] in [ '_config', '_indexes', '_relation',
                '_order', '_parent' ]:
                continue
            attr_name=col[0]
            if len(_model_primary_keys):
                attr_type=self._parse_column(col[1], True)
            else:
                attr_type=self._parse_column(col[1])

            _attributes.append((attr_name, attr_type))
        if relation!=None:
            for field, rel in relation.iteritems():
                if rel['type']=='one2one':
                    _reference='Reference'
                    _attributes.append((field, '{0}({1}_id, "{2}.{3}")' \
                        .format(_reference, field, self._generate_model_name(\
                        rel['foreignTable']), rel['foreignKey'])))
                    _relations.append(('application.model.base.{0}Base' \
                        .format(self._generate_model_name(
                            rel['foreignTable'])),
                            '{0}Base'.format(self._generate_model_name(
                                rel['foreignTable']))))
                elif rel['type']=='many2one':
                    _reference='ReferenceSet'
                    _attributes.append((field, '{0}'.format(
                        '{0}("{1}.{2}", "{3}.{4}")'.format(
                        _reference,
                        self._generate_model_name(table),
                        rel['localKey'], self._generate_model_name(
                            rel['foreignTable']), rel['foreignKey']))))
                    _relations.append(('application.model.base.{0}Base' \
                    .format(self._generate_model_name(rel['foreignTable'])),
                        '{0}Base'.format(self._generate_model_name(
                            rel['foreignTable']))))
                elif rel['type']=='many2many':
                    _reference='ReferenceSet'
                    reference=_reference+'('
                    reference+=self._parse_relation(rel, table)
                    reference+=')'
                    _attributes.append(('{0}'.format(field), reference))
                    #_relations.append(('application.model.base.{0}Base' \
                    #.format(self._generate_model_name(rel['foreignTable'])),
                    #    '{0}Base'.format(self._generate_model_name(
                    #        rel['foreignTable']))))
                    _relations.append((
                        'application.model.relation.{0}'.format(
                            self._generate_model_name(table)+\
                            self._generate_model_name(rel['foreignTable'])),
                        self._generate_model_name(table)+\
                        self._generate_model_name(rel['foreignTable'])
                    ))

        reverse=self._schema.find_reverse_reference(table)
        if reverse!=None:
            reverse_reference='ReferenceSet('
            reverse_reference+=self._parse_relation(reverse, table, True)
            reverse_reference+=')'
            _attributes.append(('{0}'.format(reverse['field']),
                reverse_reference))
            _relations.append((
                'application.model.relation.{0}'.format(
                    self._generate_model_name(reverse['foreignTable'])+\
                    self._generate_model_name(table)),
                self._generate_model_name(reverse['foreignTable'])+\
                self._generate_model_name(table)
            ))

        return (model_name, t.evoque(
            model_name=model_name,
            model_creation_date=datetime.now(),
            model_file='application/model/base/{0}'.format(model_name),
            model_table='{0}'.format(table),
            model_primary_keys=_model_primary_keys,
            attributes=_attributes,
            relations=_relations
        ))

    def generate_many_2_many(self, table, columns):
        if columns.get('_relation')==None:
            return None

        models=[]
        for field, relation in columns['_relation'].iteritems():
            if not self._analyze(relation):
                raise SchemaException('%s table has an invalid _relation ' \
                    'section, please fix it!!!'%(table))
            if relation['type']!='many2many':
                continue   # Not a m2m relationship

            t=self._mgr.get_sys_domain().get_template(\
                'tpl/modelrelation.evoque')
            modelSuffix=''.join([ word.capitalize() \
                    for word in table.split('_') ])
            modelPreffix=''.join([ word.capitalize() \
                    for word in relation['foreignTable'].split('_') ])
            model_name=modelSuffix+modelPreffix
            _model_primary_keys=self._generate_primary_keys(relation['keys'])
            _attributes=[]
            for key in relation['keys']:
                attr_name=key if type(key)==str else key.keys()[0]
                attr_type='Int()'
                _attributes.append((attr_name, attr_type))
            if relation.get('fields')!=None:
                for field in relation['fields']:
                    for fname, fvalue in field.iteritems():
                        attr_name=fname
                        attr_type=self._parse_column(fvalue, True)
                        _attributes.append((attr_name, attr_type))

            models.append((model_name, t.evoque(
                model_name=model_name,
                model_creation_date=datetime.now(),
                model_file='application/model/relation/{0}'.format(model_name),
                model_table='{0}'.format(table+'_'+relation['foreignTable']),
                model_primary_keys=_model_primary_keys,
                attributes=_attributes
            )))

        return models

    def write_base_model(self, mod_name, tpl):
        fp=file('application/model/base/{0}Base.py'.format(mod_name), 'w')
        fp.write(tpl.encode('utf8'))
        fp.close()

    def write_model(self, mod_name, tpl):
        fp=file('application/model/{0}.py'.format(mod_name), 'w')
        fp.write(tpl.encode('utf8'))
        fp.close()

    def write_relation(self, mod_name, tpl):
        fp=file('application/model/relation/{0}.py'.format(mod_name), 'w')
        fp.write(tpl.encode('utf8'))
        fp.close()

    def _generate_model_name(self, table):
        return ''.join([ word.capitalize() for word in table.split('_') ])

    def _check_composed_keys(self, cols):
        keys=[]
        for name, col in cols.iteritems():
            if col in ['_relation', '_config', '_indexes']: continue
            if 'primaryKey' in col:
                keys.append(name)
        if len(keys)>1:
            return self._generate_primary_keys(keys)

        return ''

    def _generate_primary_keys(self, keys):
        _new_keys=[]
        for key in keys:
            if type(key)==str: _new_keys.append(key)
            elif type(key)==dict: _new_keys.append(key.keys()[0])

        return '__storm_primary__ = '+','.join([ '"'+k+'"' \
                for k in _new_keys ])

    def _analyze(self, config):
        """Analyzes a table _config section"""
        if config.get('type')==None or config.get('foreignTable')==None:
            return False

        return True

    def _parse_column(self, col, special=False):
        _primary='False'
        _allow_none='True'
        _default_value='Undef'
        _foreign_keys=False
        if col.get('type')!=None:
            if col.get('primaryKey')!=None and col.get('primaryKey')==True:
                _primary='True'
            if col.get('required')!=None and col.get('required')==True:
                _allow_none='False'
            if col.get('default')!=None:
                _default_value=col.get('default')

            if not special:
                return '{0}(primary={1}, value={2}, allow_none={3})' \
            .format(tr(col.get('type')), _primary, _default_value, _allow_none)
            else:
                return '{0}(value={1}, allow_none={2})' \
            .format(tr(col.get('type')), _default_value, _allow_none)

    def _parse_relation(self, rel, table, reverse=False):
        """Parses a model table relation."""
        _new_keys=[]
        for key in rel['keys']:
            if type(key)==str:
                _new_keys.append(key)
            elif type(key)==dict:
                _new_keys.append(key.keys()[0])

        if not reverse:
            ret='"{0}.{1}", '.format(self._generate_model_name(table),
                rel['localKey'])
            ret+='"{0}.{1}", '.format(self._generate_model_name(table)+\
                self._generate_model_name(rel['foreignTable']), _new_keys[0])
            ret+='"{0}.{1}", '.format(self._generate_model_name(table)+\
                self._generate_model_name(rel['foreignTable']), _new_keys[1])
            ret+='"{0}.{1}"'.format(self._generate_model_name(rel['foreignTable']),
                rel['foreignKey'])
        else:
            ret='"{0}.{1}", '.format(self._generate_model_name(table),
                rel['localKey'])
            ret+='"{0}.{1}", '.format(self._generate_model_name(
                rel['foreignTable'])+
                self._generate_model_name(table), _new_keys[0])
            ret+='"{0}.{1}", '.format(self._generate_model_name(
                rel['foreignTable'])+\
                self._generate_model_name(table), _new_keys[1])
            ret+='"{0}.{1}"'.format(self._generate_model_name(rel['foreignTable']),
                rel['foreignKey'])

        return ret