On the ORM design in Python web framework

Source: Internet
Author: User

Look at the Liaoche of the web framework, is actually encapsulated the web.py, the request to use asynchronous and will aiomysql做 provide the MySQL database asynchronous IO driver, the front-end part of the integration of Jinja. The hardest part of this is the ORM section.

Here is a simple example of ORM.

classUser (Model):__table__='Users'ID= Stringfield (Primary_key=true, default=next_id, ddl='varchar (+)') Email= Stringfield (ddl='varchar (+)') passwd= Stringfield (ddl='varchar (+)') Admin=Booleanfield () name= Stringfield (ddl='varchar (+)') Image= Stringfield (ddl='varchar (+)') Created_at= Floatfield (Default=time.time)

Overall, this is a simple table for the user, integrated with the model class. Then the fields are the various types of field.

1. First look at the fields, which is the field section. The field section is relatively simple, inherits the object, and initializes some fields, in fact there is nothing to say. When assigning values to a field, the parameter is passed in dict format, where is the dict of the type, but the following code changes the original type with __new__, and the meta-class is the class that creates the class, so the field field parameter, will be handled in the Modelmetaclass class.

classModelmetaclass (type):def __new__(CLS, name, bases, attrs):ifname=='Model':            returnType.__new__(CLS, name, bases, attrs) TableName= Attrs.get ('__table__', None)orname Logging.info ('found Model:%s (table:%s)'%(name, tableName)) Mappings=dict () fields=[] PrimaryKey=None forKvinchAttrs.items ():ifisinstance (V, Field): Logging.info ('found mapping:%s ==>%s'%(k, V)) Mappings[k]=vifV.primary_key:#Locate the primary key:                    ifPrimaryKey:RaiseStandardError ('Duplicate primary key for field:%s'%k) PrimaryKey=kElse: Fields.Append (k)if  notPrimaryKey:RaiseStandardError ('Primary key not found.')         forKinchMappings.keys (): Attrs.pop (k) Escaped_fields= List (Map (LambdaF:''%s ''%f, fields)) attrs['__mappings__'] = Mappings#Saving mappings for properties and columnsattrs['__table__'] =tableName attrs['__primary_key__'] = PrimaryKey#primary Key property nameattrs['__fields__'] = Fields#attribute name except primary keyattrs['__select__'] ='Select '%s ',%s from '%s ''% (PrimaryKey,', '. Join (Escaped_fields), tableName) attrs['__insert__'] ='insert INTO '%s ' (%s, '%s ') values (%s)'% (TableName,', '. Join (Escaped_fields), PrimaryKey, Create_args_string (len (escaped_fields) + 1)) attrs['__update__'] ='Update '%s ' set%s where '%s ' =?'% (TableName,', '. Join (Map (LambdaF:''%s ' =?'% (Mappings.get (f). Nameorf), fields), PrimaryKey) attrs['__delete__'] ='Delete from '%s ' where '%s ' =?'%(TableName, PrimaryKey)returnType.__new__(CLS, name, bases, Attrs)

The model class is relatively simple, mainly in order to initialize the Get/set and a few getvalue functions, this piece according to their own needs to look at good.

classModel (Dict, metaclass=modelmetaclass):def __init__(Self, * *kw): Super (Model, self).__init__(**kw)def __getattr__(self, key):Try:            returnSelf[key]exceptKeyerror:RaiseAttributeerror (R"' Model ' object has no attribute '%s '"%key)def __setattr__(self, Key, value): Self[key]=valuedefGetValue (self, key):returngetattr (self, Key, None)defGetValueOrDefault (self, key): Value=getattr (self, Key, None)ifValue isNone:field= self.__mappings__[key]ifField.default is  notNone:value= Field.default ()ifCallable (Field.default)ElseField.default Logging.debug ('using default value for%s:%s'%(Key, str (value))) SetAttr (self, key, value)returnvalue @classmethod @asyncio. CoroutinedefFindnumber (CLS, Selectfield, Where=none, args=None):'find number by Select and where.'SQL= ['Select%s _num_ from '%s ''% (Selectfield, CLS.__table__)]        ifWhere:sql.append ('where') Sql.append (where) RS=yield  fromSelect' '. Join (SQL), args, 1)        ifLen (rs) = =0:returnNonereturnrs[0]['_num_']

....

The @classmethod is to turn the method into a class method, @asyncio. Coroutine is to do asynchronous processing.

On the ORM design in Python web framework

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.