Django之ORM篇 —— 建表

        早在2019年还在老家上班的时候就买了路飞学城的python课,断断续续的学着,知道北漂后才真正的意识到IT这行的台阶有多高,就像郭德纲老师说的:“这行儿门槛儿在门里呢~~”。其实不只是相声,IT这行也是。随随便便学点儿,找个一万多块钱的工作很简单,但是能不能挣到更高的薪资,拥有更深的技术,成为更有价值的角色都得看自己后天是不是成长型人格,靠混!到进盒儿那天也不会有行里人知道你是谁。就这这股热乎劲儿,把这阵儿学的知识总结一下,若有不到之处请大家多多指正~~~!!!

        ORM是Django框架中,利用python代码的形式代替传统SQL操作数据库的方式,英文全称为Object Relational Mapping,译为“对象关系映射”。其实不止python,许多面向对象的语言都有这类操作,比如Java的Hibernate和最常用的MyBatis。说到MyBatis,个人觉得它更像是一个“半兽人”,虽然也需要写SQL,不像Hibernate或者Django的这种全表映射,但是对SQL的自动优化及对存储过程的支持使得MyBatis具有更强的战力。

        Django的ORM实际是应用了django.db下的一个models类,所有的操作基本上都是对该类对象及方法的使用。ORM的使用因项目而异,尽管我见过的大部分项目都是写SQL或者MyBatis这种“半兽人”,但是从异构数据库的迁移方面来说,我更倾向与这种跨库的代码。虽然作为一名DBA不应该在性能上打折,但是从项目成本考虑,使用ORM无疑是一种优秀的选择,退一万步讲,即使不用,django提供了这种技术,也是应该学习研究的,因为我坚信一点,没有无用的技术,只有错误的位置,技术放在对的地方就会发挥最大的价值。

        说到这就不得不提及ORM的优缺点了,鄙人暂时了解的ORM:

优点:

        1. 方便跨库迁移,更换底层数据库时不需重构代码,只需修改settings配置即可。

        2. 操作简单,完全是python的语法,不需要复杂的SQL编写,对SQL比较low的开发人员更友好。

        3. 开发效率更高,可以配合python代码逻辑对结果集进行处理,不需占用数据库的计算能力。

缺点:

        1. 只能进行表级操作,无法做到库级操作。

        2. 不支持复杂的SQL,如存储过程。 

ORM创建表结构:

        在ORM创建表结构之前,需要在数据库中手动建好schema,并在settings文件中配置数据库连接信息及SQL转换的日志,配置连接到我本地虚拟机建的库:

        

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'orm',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '192.168.189.101',
        'PORT': 3306
    }
}



LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level': 'DEBUG',
        },
    }
}

而见表语句则是在app中的models文件中的类,这里不了解Django目录结构的同学可自行度娘撒:

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    state = models.BooleanField()
    pub_date = models.DateField()
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish = models.CharField(max_length=32)

在项目的__init__.py文件中应用pymysql,注意是项目的,不是app的:

import pymysql
pymysql.install_as_MySQLdb()

之后在pycharm的终端里或者系统终端输入数据库迁移命令:

(venv) D:\test_python\ORM>python manage.py makemigrations  -- 此时还没有生成Book表
(venv) D:\test_python\ORM>
(venv) D:\test_python\ORM>
(venv) D:\test_python\ORM>python manage.py migrate  -- 生成Book表及ORM自动创建的表

执行命令后,在数据库中生成如下表:

mysql> show tables;
+----------------------------+
| Tables_in_orm              |
+----------------------------+
| app01_book                 |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
11 rows in set (0.00 sec)

其中app01_book表即为models.py中,Book类生成的表,明明方式为:应用名称_表名小写。其余表为ORM自动创建用于转换所需。我们来看一下自建表的表结构:

mysql> show create table app01_book;
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                                                                                                                                                                                               |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| app01_book | CREATE TABLE `app01_book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(32) COLLATE utf8mb4_bin NOT NULL,
  `state` tinyint(1) NOT NULL,
  `pub_date` date NOT NULL,
  `price` decimal(8,2) NOT NULL,
  `publish` varchar(32) COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

从中可以看出Book类的语法与字段类型的对应关系。由于我在参数文件中指定了字符集且MySQL5.7的默认存储引擎就是InnoDB,因此我试着在类里使用MyISAM存储引擎见表,需要在settings文件中添加参数:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'orm',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '192.168.189.101',
        'PORT': 3306,
        'OPTIONS': {
            'init_command': 'SET default_storage_engine=MyISAM;'
        }
    }
}

表结构如下:


mysql> show create table app01_book;
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                                                                                                                                                                                               |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| app01_book | CREATE TABLE `app01_book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(32) COLLATE utf8mb4_bin NOT NULL,
  `state` tinyint(1) NOT NULL,
  `pub_date` date NOT NULL,
  `price` decimal(8,2) NOT NULL,
  `publish` varchar(32) COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

但是这种方法很麻烦,我本以为在models的类中可以控制存储引擎,但是并没有找到方法,虽然大部分的生产业务中都是使用InnoDB存储引擎,但是不能自由指定让我觉得很不爽,况且在settings中增加的参数只是在创建表时执行一条set的命令,了解MySQL的人都明白他的原理,只是改了动态参数的值,或许有其他方法只是我还没找到。 不过通过这个操作让我了解到,ORM不会覆盖已创建的表,因为我直接执行迁移命令时ENGINE还是InnoDB,直到我把表drop掉之后(其实我是drop的库)重新实行两个迁移命令再见表时才是MyISAM。

        本片至此,行文不多,内容简单,未完待续。。。。。。

 

 

 

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值