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

因为买了本机器学习的书是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 entities
import BusinessBase
def 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 inspect
import types
class 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
                 }
                 }



你可能感兴趣的:(一个简单的python MVC框架(1))