早在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。
本片至此,行文不多,内容简单,未完待续。。。。。。