Django ORM源码解析(一)

作者: admin 分类: 公众号存档            2 次浏览 发布时间: 2018-09-24 23:30

公众号:杨建荣的学习笔记 · 作者:杨建荣 · 发布:2018-09-24 23:30:55 · 原文链接

 这是学习笔记的第 1754篇文章

   今天来解读下Django的源码内容,也算在中秋节完成一次技术任务。

    对于Django的ORM也算是目前我最喜欢的一个特性了。这个特性和Java方向的Hibernate类似,都是做了对象关系映射,算是一个中间层,哪怕对数据库不够了解,也可以完成基本的数据操作,对于底层的技术细节可以屏蔽,而通过API的形式来对接,从效率和易用性上来说都很不错。 

    这个特性的解读我是通过python manage.py这个命令开始的,Django里面的服务启动内置了manage.py文件,可以完成服务的启动,ORM的配置等,所以这是一个很重要的入口文件。

    这个manage.py文件的功能非常重要,代码量多大呢,其实就几行内容。

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "OpsManage.settings")

    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)

其实可以看到,很多技术细节都被屏蔽了,我们来先简单看下sys.argv的值,这个对于我们了解manage.py的运行机制很重要,我们简单加入一行print即可,可以看到这个命令的输入如下:

/usr/local/python2.7/bin/python2.7 /root/devopsdb/devopsdb/manage.py runserver 192.168.56.102:8000
['/root/devopsdb/devopsdb/manage.py', 'runserver', '192.168.56.102:8000']
['/root/devopsdb/devopsdb/manage.py', 'runserver', '192.168.56.102:8000']

我们启动服务的时候,使用的选项是runserver,而ORM的部分,选项则是migrate,makemigrations,sqlmigrate等,所以在这里其实是一个选项集合。

我们来根据上面的代码入口进入方法execute_from_command_line的细则,会发现其实是通过一个类来触发的,这个类ManageUtility提供了多个方法,其中execute方法则是里面的核心方法。

明白了上面的选项的意义,其实我们在ORM里面的选项主要是sqlmigrate,migrate,makemigrations,我们就选取一个重点,比如sqlmigrate,可以在当前文件看到调用的基本信息。

def call_command(name, *args, **options):
    """
    Calls the given command, with the given options and args/kwargs.

    This is the primary API you should use for calling specific commands.

    Some examples:
        call_command('syncdb')
        call_command('shell', plain=True)
        call_command('sqlmigrate', 'myapp')
    """
    # Load the command object.
    try:
        app_name = get_commands()[name]

这个方法的调用情况如何呢,我们可以通过调用关系看到,其实就是migrate.py文件了,所以,我们的选项sqlmigrate,makemigrations等都会有一个独立的文件来映射。 

简单看一下migrate的内容,可以看到里面的方法其实不多,核心方法是handle,这个是真正触发的环节,对于sqlmigrate来说,函数的定义情况是类似的。

在sqlmigrate.py文件里面我们可以看到一些基本的逻辑了,首先要定位到这个migration文件,然后对比schema的细节生成基本的计划,然后根据提供的计划信息,在已有的配置规则中动态生成SQL,下面的部分就是根据提供的计划信息来匹配规则生成SQL

这个collect_sql方法里面对于schema的处理,可以看到会映射多个schema_editor方法,我们使用的是MySQL,所以这个映射关系可以直接指向MySQL相关的,如果不是则需要做一个关联匹配。

这些规则信息在哪里映射呢,其实是在schema.py文件里面,怎么去映射SQL的细节,在这里都可以看到一个基本的情况。

后续继续跟进。

admin

杨建荣,《Oracle DBA工作笔记》《MySQL DBA工作笔记》作者,dbaplus社群发起人之一,腾讯云TVP,现任竞技世界系统部经理,拥有十多年数据库开发和运维经验,目前专注于开源技术、运维自动化和性能调优

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注