Getting started with writing an ORM framework in Python

Source: Internet
Author: User

Getting started with writing an ORM framework in Python

This article mainly introduces how to compile the ORM framework in Python. The sample code is based on Python2.x. For more information, see

With the db module, It is very convenient to directly write SQL statements to the database. However, we still lack ORM. If you have an ORM, you can use a statement like this to obtain the User object:

?

1

User = User. get ('20140901 ')

Instead of writing SQL statements, convert them to User objects:

?

1

2

U = db. select_one ('select * from users where id =? ', '123 ')

User = User (** u)

So we started to write the ORM module: transwarp. orm.

Design An ORM Interface

Similar to designing a db module, designing an ORM is also designed from the perspective of upper-layer callers.

We first consider how to define a User object, and then associate the database table users with it.

?

1

2

3

4

5

6

From transwarp. orm import Model, StringField, IntegerField

 

Class User (Model ):

_ Table _ = 'users'

Id = IntegerField (primary_key = True)

Name = StringField ()

Note that _ table _, id, and name defined in the User class are the attributes of the class, not the attributes of the instance. Therefore, attributes defined at the class level are used to describe the User ing between the User object and the table, and instance attributes must be initialized using the _ init _ () method, so they do not interfere with each other:

?

1

2

3

4

# Create an instance:

User = User (id = 123, name = 'Michael ')

# Database storage:

User. insert ()

Implement the ORM Module

With the definition, we can start to implement the ORM module.

The first thing to define is the base class Model of all ORM ing:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Class Model (dict ):

_ Metaclass _ = ModelMetaclass

 

Def _ init _ (self, ** kw ):

Super (Model, self). _ init _ (** kw)

 

Def _ getattr _ (self, key ):

Try:

Return self [key]

Failed t KeyError:

Raise AttributeError (r "'dict 'object has no attribute '% S'" % key)

 

Def _ setattr _ (self, key, value ):

Self [key] = value

Model inherits from dict, so it has all dict functions and implements special methods _ getattr _ () and _ setattr __(), therefore, you can write data as if you reference a common field:

?

1

2

3

4

>>> User ['id']

123

>>> User. id

123

Model is only a base class. How can we read the ing information of specific sub-classes such as users? The answer is through metaclass: ModelMetaclass:

?

1

2

3

4

5

6

7

8

9

10

Class ModelMetaclass (type ):

Def _ new _ (cls, name, bases, attrs ):

Mapping =... # Read the cls Field

Primary_key =... # search for the primary_key Field

_ Table _ = cls. _ talbe _ # Read the _ table _ field of cls.

# Add some fields to cls:

Attrs ['_ mapping _'] = mapping

Attrs ['_ primary_key _'] = _ primary_key __

Attrs ['_ table _'] = _ table __

Return type. _ new _ (cls, name, bases, attrs)

In this way, any class (such as User) inherited from the Model will automatically scan the ing relationship through ModelMetaclass and store it in its own class.

Then, we add the class method to the Model class so that all subclasses can call the class method:

?

1

2

3

4

5

6

7

8

Class Model (dict ):

 

...

 

@ Classmethod

Def get (cls, pk ):

D = db. select_one ('select * from % s where % s =? '% (Cls. _ table __, cls. _ primary_key _. name), pk)

Return cls (** d) if d else None

The User class can be used to find the primary key through the class method:

User = User. get ('20140901 ')

To add an instance method to the Model class, you can have all subclass call the instance method:

?

1

2

3

4

5

6

7

8

9

10

Class Model (dict ):

 

...

 

Def insert (self ):

Params = {}

For k, v in self. _ mappings _. iteritems ():

Params [v. name] = getattr (self, k)

Db. insert (self. _ table __, ** params)

Return self

In this way, you can save a User instance to the database:

?

1

2

User = User (id = 123, name = 'Michael ')

User. insert ()

The last step is to improve the ORM. We can implement the following methods for searching:

?

1

2

3

4

5

Find_first ()

 

Find_all ()

 

Find_by ()

For count, you can:

?

1

2

3

Count_all ()

 

Count_by ()

And the update () and delete () methods.

Finally, let's take a look at how many lines of code are implemented in the ORM module? Only over 300 lines are added with comments and doctest. Is it easy to write an ORM using Python?

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.