makemigrations 和 migrate工作原理分别是什么

有一道关于python-django开发工程师的面试题:

  • 内容大致是makemigrations 和 migrate 工作原理分别是什么,
  • 如果不想使用 Django 的 makemigrations 和 migrate 功能,但是不小心执行了这两个命令会发生什么,
  • 如何禁用 migrate 的功能。

下面我们来分析一下这几个问题。

首先:
manage.py是每个django项目中自动生成的一个用于管理项目的脚本文件。需要通过python命令执行。manage.py接受的是Django提供的内置命令。

内置命令包含:

  • check
  • makemigrations
  • migrate
  • runserver
  • startapp
  • startproject
  • 还有其他的我先不写了,这是比较常用的
  • 本篇文章主要根据题目分析makemigrations和migrate

makemigrations:

  • 根据检测到的模型创建新的迁移。迁移的作用,更多的是将数据库的操作,以文件的形式记录下来,方便以后检查、调用、重做等等。

有这样一道很熟悉的命令:

python manger.py makemigrations

相当于在该app下建立 migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py。
但是 这个改动还没有作用到数据库文件
在这里插入图片描述

个人白话翻译:也就是说你改了models的时候,你就得删了0001这个日志文件,然后删库重来 python manage.py makemigrations 创建新的迁移

migrate:

  • 使数据库状态与当前模型集和迁移集同步。说白了,就是将对数据库的更改,主要是数据表设计的更改,在数据库中真实执行。例如,新建、修改、删除数据表,新增、修改、删除某数据表内的字段等等。

个人白话翻译:你改了models的时候,数据库也会真实的执行。

在python manger.py makemigrations之后执行命令:

python manager.py migrate

  
  

    就将该改动作用到数据库文件

    如何禁用migrate的功能:

    Django < 1.9版本时

    from settings import *
    class DisableMigrations(object):
        def __contains__(self, item):
            return True
        def __getitem__(self, item):
            return 'notmigrations'
    MIGRATION_MODULES = DisableMigrations()
    
      
      

      Django >= 1.9版本时
      有这么一个配置项目 MIGRATION_MODULES。

      from settings import *
      MIGRATION_MODULES = {
          'auth': None,
          'contenttypes': None,
          'default': None,
          'sessions': None,
          'core': None,
          'profiles': None,
          'snippets': None,
          'scaffold_templates': None,
      
        
        

        其他Django版本:

        SOUTH_TESTS_MIGRATE = False
        

        基于元类设计的makemigrations和migrate

        makemigrations和migrate是两条基于元类设计的Django ORM数据库命令

        python的元类:

        元类就是用来创建类的“东西”。你创建类就是为了创建类的实例对象。
        元类就是用来创建这些类(对象)的,元类就是类的类

        基于django-ORM的元类

        ORM:对象关系映射.
        用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。
        其本质是通过调用对象实现同等的sql语句

        我们来看下面代码:

        class Field(object):
            def __init__(self,name,column_tyoe):
                self.name = name
                self.column_type = column_tyoe
            def __str__(self):
                return '&lt;%s:%s&gt;'%(self.__class__.__name__,self.name)
        
        class StringField(Field):
            def __init__(self,name):
                super(StringField,self).__init__(name,"varchar(100)")
        
        class IntegerField(Field):
            def __init__(self,name):
                super(IntegerField,self).__init__(name,"bigint")
        
        class ModelMetaClass(type):
            def __new__(cls, name,bases,attrs):
                if name == "Model":
                    return type.__new__(cls,name,bases,attrs)
                print('found model:%s'%name)
                mapping = dict()
                for k,v in attrs.items():
                    if isinstance(v,Field):
                        print("Found mapping:%s ==&gt;%s"%(k,v))
                        mapping[k] = v
                for k in mapping.keys():
                    attrs.pop(k)
                attrs['__mappings__'] = mapping
                attrs['__table__'] = name
                return type.__new__(cls,name,bases,attrs)
        
        class Model(dict,metaclass = ModelMetaClass):
            def __init__(self,**kwargs):
                super(Model,self).__init__(**kwargs)
            def __getattr__(self, key):
                try:
                    return self[key]
                except KeyError:
                    raise AttributeError("Module objects has no attribute %s"%key)
            def __setattr__(self, key, value):
                self[key] = value
        
            def save(self):
                fields = []
                args = []
                for k,v in self.__mappings__.items():
                    fields.append(v.name)
                    args.append(getattr(self,k,None))
                sql = 'insert into %s (%s) values (%s)'%(self.__table__,",".join(fields),",".join(str(i) for i in args))
                print("SQL:%s"%sql)
                print("ARGS: %s"%str(args))
        

        class User(Model):
        # 定义类的属性到列的映射:
        id = IntegerField(‘id’)
        name = StringField(‘username’)
        email = StringField(‘email’)
        password = StringField(‘password’)

        u = User(id=12345, name=‘Batman’, email=‘batman@nasa.org’, password=‘iamback’)
        u.save()

        中心思想: 用元类来创建user类,id、name、email、password等属性。传递到元类,元类接受之后把他们转换成字典,用_ _mapings保存,也就是user用__table__保存.

        本篇整合:

        1、makemigrations 和 migrate 工作原理分别是什么:

        • makemigrations:根据检测到的模型创建新的迁移。迁移的作用,更多的是将数据库的操作,以文件的形式记录下来,方便以后检查、调用、重做等等。
        • migrate:使数据库状态与当前模型集和迁移集同步。说白了,就是将对数据库的更改,主要是数据表设计的更改,在数据库中真实执行。例如,新建、修改、删除数据表,新增、修改、删除某数据表内的字段等等。

        2、如果不想使用 Django 的 makemigrations 和 migrate 功能,但是不小心执行了这两个命令会发生什么,

        • 首先在该app下建立 migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py,
        • 接着执行migrate的话,这时候会作用到数据库文件,产生对应的表

        3、如何禁用 migrate 的功能。

        • 详情见文中各版本对应设置。
        • 2
          点赞
        • 13
          收藏
          觉得还不错? 一键收藏
        • 3
          评论
        makemigrations和migrate是Django中的两个相关但不同的命令。makemigrations命令用于创建数据库迁移文件,当你在Django中修改了模型的结构时,需要运行makemigrations命令来生成一个包含这些修改的迁移文件。迁移文件包含了数据库模式的变化,包括创建、修改或删除表、添加或删除字段等。而migrate命令用于执行数据库迁移,即将模型的变化应用到数据库中的过程。当你运行migrate命令时,Django会检查迁移文件,并将其中的变化应用到数据库中,确保数据库的结构与模型的结构保持一致。简而言之,makemigrations用于生成数据库迁移文件,而migrate用于将迁移文件应用到数据库中。makemigrations是一个生成迁移文件的过程,而migrate是一个执行迁移文件的过程。如果想指定某个migrations文件,可以使用命令python manage.py migrate \[app_label\] \[migration_name\],例如python manage.py migrate cases 0011_auto_20220726_1440。\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [Django的MigrateMakemigrations讲解](https://blog.csdn.net/momoda118/article/details/120181669)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [django中migratemakemigrations 区别](https://blog.csdn.net/yuanhou110/article/details/131455342)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

        “相关推荐”对你有帮助么?

        • 非常没帮助
        • 没帮助
        • 一般
        • 有帮助
        • 非常有帮助
        提交
        评论 3
        添加红包

        请填写红包祝福语或标题

        红包个数最小为10个

        红包金额最低5元

        当前余额3.43前往充值 >
        需支付:10.00
        成就一亿技术人!
        领取后你会自动成为博主和红包主的粉丝 规则
        hope_wisdom
        发出的红包
        实付
        使用余额支付
        点击重新获取
        扫码支付
        钱包余额 0

        抵扣说明:

        1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
        2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

        余额充值