一个简单的python MVC框架(1)

来源:互联网 发布:淘宝客pid在哪里查看 编辑:程序博客网 时间:2024/05/03 16:53

因为买了本机器学习的书是python的,所以学习了一下python,就用python做了一个简单的web开发的mvc小框架。整个框架分为实体层,数据访问层,业务基类层,Web请求转发层,控制层和视图层。当然也包括一些辅助性工具类。下面一一介绍,希望对跟我一样初学python的有点帮助:
1)实体层
      由实体基类和用户实体类组成。实体类可以由数据库自动生成,提供了一个DbTools,可以自动生成规则的实体。下面是实体基类:
    

import threading#用户错误类,用于抛出自定义的异常class CustomError(RuntimeError):      def __init__(self,args):          self.args=args#实体的基类.          class EntityB:    def __init__(self):        self.CurrFields=[]    #根据属性名获取属性值    def GetValueByName(self,FieldName):        if hasattr(self,FieldName):            return getattr(self,FieldName)        return None    #根据属性名设置属性值    def SetValueByName(self,FieldName,Value):        if hasattr(self,FieldName):            return setattr(self,FieldName,Value)    #定义了该属性,对象可枚举.    def __getitem__(self,key):        if type(key)==type('abc'):            return self.GetValueByName(key)        if type(key)==type(1):            theFld = self.CurrFields[key]            return self.GetValueByName(theFld)        return None    #设置属性值,key可以是索引,也可以是属性名.    def __setitem__(self,key,value):        if type(key)==type('abc'):            self.SetValueByName(key,value)        if type(key)==type(1):            theFld = self.CurrFields[key]            self.SetValueByName(theFld,value)    #获取实体的表名.    def GetTableName(self):        theType = type(self)        if hasattr(theType,'TableName'):            return getattr(theType,'TableName')        return ''    #获取关键字段名    def GetKeyField(self):        theType = type(self)        if hasattr(theType,'KeyField'):            return getattr(theType,'KeyField')        return ''    #获取字段名集合    def GetFields(self):        theType = type(self)        if hasattr(theType,'Fields'):            return getattr(theType,'Fields')        return []        InsertCondition = threading.Condition()    InsertLockSign = False        DeleteCondition = threading.Condition()    DeleteLockSign = False    UpdateAllCondition = threading.Condition()    UpdateAllLockSign = False        InsertSqlName='__InsertSql'    UpdateAllSqlName='__UpdateSql'    DelByPKSqlName='__DelByPKSql'    DefaultSelectSQL='__DefaultSelectSql'    #根据属性名获取类型的属性值。    def _GetClassValue(self,AttrName):        theSelfType = type(self)        theValue =''        if hasattr(theSelfType,AttrName):           theValue=getattr(theSelfType,AttrName)        return theValue    #根据属性名设置类型的属性值.    def _SetClassValue(self,AttrName,value):        theSelfType = type(self)        theValue =''        if hasattr(theSelfType,AttrName):           setattr(theSelfType,AttrName,value)    #获取字段参数    def GetFieldParams(self):        return self._GetClassValue('FieldParams')    #获取插入的SQL    def GetInsertSQL(self):        theSQL =self._GetClassValue(EntityB.InsertSqlName)        if (theSQL==None or theSQL==''):           EntityB.InsertCondition.acquire()           try:               if EntityB.InsertLockSign:                   EntityB.InsertCondition.wait()               InsertLockSign = True               theSQL =self._GetClassValue(EntityB.InsertSqlName)               if (theSQL==None or theSQL==''):                   theTableName=self.GetTableName()                   theFields=self.GetFields()                   if theTableName=='' or theFields==[]:                       raise CustomError('表名或字段为空!')                   theSQL='INSERT INTO '+ theTableName                   theFlds=''                   theVals=''                   theFldParams = self.GetFieldParams()                   for theF in theFields:                       if theFlds=='':                           theFlds += theF                           theVals += theFldParams[theF]['DSFmt']                       else:                           theFlds += ','+theF                           theVals +=','+theFldParams[theF]['DSFmt']                   theSQL+='('+theFlds+') values('+theVals+')'                   self._SetClassValue(EntityB.InsertSqlName,theSQL)               return theSQL           finally:               InsertLockSign=False               EntityB.InsertCondition.notify()               EntityB.InsertCondition.release()        else:           return theSQL    #获取根据主键删除SQL    def GetDelByPKSQL(self):        theSQL =self._GetClassValue(EntityB.DelByPKSqlName)        if (theSQL==None or theSQL==''):           EntityB.DeleteCondition.acquire()           try:               if EntityB.DeleteLockSign:                   EntityB.DeleteCondition.wait()               DeleteLockSign = True               theSQL =self._GetClassValue(EntityB.DelByPKSqlName)               if (theSQL==None or theSQL==''):                   theTableName=self.GetTableName()                   theKeyField=self.GetKeyField()                   if theTableName=='' or theKeyField=='':                       raise CustomError('表名或主键为空!')                   theFldParams = self.GetFieldParams()                   theSQL='DELETE FROM '+ theTableName+' WHERE '+theKeyField+'='+theFldParams[theKeyField]['DSFmt']                   self._SetClassValue(EntityB.DelByPKSqlName,theSQL)               return theSQL           finally:               DeleteLockSign=False               EntityB.DeleteCondition.notify()               EntityB.DeleteCondition.release()        else:           return theSQL    #获取更新所有字段的SQL语句(根据主键更新)    def GetUpdateAllSQL(self):        theSQL =self._GetClassValue(EntityB.UpdateAllSqlName)        if (theSQL==None or theSQL==''):           EntityB.UpdateAllCondition.acquire()           try:               if EntityB.UpdateAllLockSign:                   EntityB.UpdateAllCondition.wait()               UpdateAllLockSign = True               theSQL =self._GetClassValue(EntityB.UpdateAllSqlName)               if (theSQL==None or theSQL==''):                   theTableName=self.GetTableName()                   theFields=self.GetFields()                   theKeyField=self.GetKeyField()                   if theTableName=='' or theFields==[] or theKeyField=='':                       raise CustomError('表名、主键或字段为空!')                   theSQL='UPDATE '+ theTableName +' SET '                   theFlds=''                   theFldParams = self.GetFieldParams()                   for theF in theFields:                       if(theF != theKeyField):                           if theFlds=='':                               theFlds += theF+'= '+theFldParams[theF]['DSFmt']                           else:                               theFlds += ','+theF+'= '+theFldParams[theF]['DSFmt']                   theSQL+= theFlds +' WHERE '+theKeyField+'='+theFldParams[theKeyField]                   self._SetClassValue(EntityB.UpdateAllSqlName,theSQL)               return theSQL           finally:               UpdateAllLockSign=False               EntityB.UpdateAllCondition.notify()               EntityB.UpdateAllCondition.release()        else:           return theSQL    #获取缺省的查询SQL    def GetDefaultSelectSQL(self):        theTableName=self.GetTableName()        return 'SELECT * FROM ' + theTableName + ' WHERE 1=1'    #def __delitem__(self)           


有关实体的通用操作SQL都是动态产生的,但不是每次都去产生,而是缓存在类型下。所为实体,做如下建议:
1)通用的SQL可以先产生,或者动态产生,但缓存;
2)一般查询SQL,特别是带条件的,尽量不要动态产生,也不要使用类似EF框架的那种,无论是管理性能还是扩展都是灾难;
3)一般不要把实体关系固化,如早期Hibernate的那种方式,就是在数据库里也不要建外间关系,去根据业务需要转化为业务逻辑,一般系统大一点,或者在分布式结构下,去固化实体关系,或者把实体关系映射放到内存或者配置文件中,都是一种灾难。

下面的类是辅助工具类:

#Generate entitiesimport BusinessBasedef GetFmtStr(datatype):    if datatype.find('varchar')>=0:        return '%s'    elif datatype.find('date')>=0:        return '%s'    else:        return '%s'def IntToStr(iData=0):    if iData==None:        return '0'    return '%d' % iData;theFile = open(r"EntitiesL.py", "w")try:    theDb = BusinessBase.BusinessBase(object)    #这里需改为从你自己的数据库XXXX    theTabs = theDb.GetDbTables('XXXX')    theFile.write("import EntityBase\n")        for theTab in theTabs:        theFile.write('class M_'+theTab.TableName.upper()+'(EntityBase.EntityB):\n')        theFile.write('    def __init__(self):\n')        theFile.write('        M_'+theTab.TableName.upper()+'.Count += 1\n')        theFile.write('        self.RefDict={}\n')        theFile.write('        self.CurrFields=[]\n')        theFile.write('    Count=0\n')            theFile.write('    TableName =\''+theTab.TableName+'\'\n')        theKeyField=''        theFlds=''        theFile.write('    FieldParams={\n')         theFields=theDb.GetTabFields('tian',theTab.TableName)        theIndex =0        for theF in theFields:            if theF.iskey==1:                theKeyField = theF.column_name                            theIndex += 1            if(theIndex>1):                theFile.write('                        ,\n')                theFlds+=',\''+theF.column_name+'\''            else:                theFlds='\''+theF.column_name+'\''            theFile.write('                  \''+theF.column_name+'\':\n')            theFile.write('                        {\n')            theFile.write('                        \'DSFmt\':\''+GetFmtStr(theF.data_type)+'\',\n')            theFile.write('                        \'DataType\':\''+theF.data_type+'\',\n')            theFile.write('                        \'Length\':'+IntToStr(theF.lengthb)+',\n')            theFile.write('                        \'Precision\':'+IntToStr(theF.precisionlen)+',\n')            theFile.write('                        \'Scale\':'+IntToStr(theF.scalelen)+'\n')            theFile.write('                        }\n')        theFile.write('                }\n')        theFile.write('    KeyField =\''+theKeyField+'\'\n')        theFile.write('    Fields =['+theFlds+']\n')      finally:    theFile.close()    

#这个类用于获取对象的自定义属性。

import inspectimport typesclass ObjOpt:    @staticmethod    def IsProperty(obj):        if(obj.__class__ is types.FunctionType):            return False        else:            return True    @staticmethod    def GetPropertyNames(obj):        theAttrs = inspect.getmembers(obj,ObjOpt.IsProperty)        theRetAttrs = []        for attr in theAttrs:            bb=attr[0].startswith('__')            if bb==False:                theRetAttrs.append(attr[0])        return theRetAttrs;    #获取类名    @staticmethod    def GetClassName(Obj):        return Obj.__name__


这是一个自动生成的实体类例子:

class M_SS01_SYS_USR(EntityBase.EntityB):    def __init__(self):        M_SS01_SYS_USR.Count += 1        self.RefDict={}        self.CurrFields=[]    Count=0    TableName ='SS01_SYS_USR'    KeyField='USR_ID'    Fields=['USR_ID','USR_NAME','USR_PWD']    FieldParams={'USR_ID':                 {                     'DSFmt':'%s',                     'DataType':'varchar',                     'Length':50,                     'Precision':0,                     'Scale':0                 },                 'USR_NAME':                 {                   'DSFmt':'%s',                   'DataType':'varchar',                     'Length':50,                     'Precision':0,                     'Scale':0                 },                 'USR_PWD':                 {                     'DSFmt':'%s',                     'DataType':'varchar',                     'Length':50,                     'Precision':0,                     'Scale':0                 }                 }



2 0
原创粉丝点击