orm mysql_ORM介绍
[TOC]
Django模型層之ORM介紹
一 ORM是什么?為何要有ORM?
? 我們在使用Django框架開發web應用的過程中,不可避免地會涉及到數據的管理操作(增、刪、改、查),而一旦談到數據的管理操作,就需要用到數據庫管理軟件,例如mysql、oracle、Microsoft SQL Server等。
? 如果應用程序需要操作數據(比如將用戶注冊信息永久存放起來),那么我們需要在應用程序中編寫原生sql語句,然后使用pymysql模塊遠程操作mysql數據庫
? 針對應用程序的數據操作,直接編寫原生sql語句會存在兩方面的問題,嚴重影響開發效率,如下
#1. sql語句的執行效率問題:應用開發程序員需要耗費一大部分精力去優化sql語句
#2. 數據庫遷移問題:針對mysql開發的sql語句無法直接應用到oracle數據庫上,一旦需要遷移數據庫,便需要考慮跨平臺問題
? 為了解決上述問題,django引入了ORM的概念,ORM全稱Object Relational Mapping,即對象關系映射,是在pymysq之上又進行了一層封裝,對于數據的操作,我們無需再去編寫原生sql,取代代之的是基于面向對象的思想去編寫類、對象、調用相應的方法等,ORM會將其轉換/映射成原生SQL然后交給pymysql執行
? 基于圖2所示,有了ORM框架,開發人員既不用再去考慮原生SQL的優化問題,也不用考慮數據庫遷移的問題,ORM都幫我們做了優化且支持多種數據庫,這極大地提升了我們的開發效率,下面就讓我們來詳細學習ORM的使用吧
二 ORM的使用之模型
? 在django的ORM框架中,繼承自django.db.models.Model的類稱之為模型類,或簡稱模型。
? 一個模型是關于你的數據,唯一的、決定性的信息源、它包含存儲數據的基本字段和方法。
? 通常,每個模型都映射到一個數據庫表。模型中的屬性對應數據庫表的字段
? 如下所示:原生SQL與ORM的模型對應關系
三 ORM的使用之數據庫遷移
3.1 創建模型
? 數據來源于數據庫的表,而ORM的模型類對應數據庫表,所以若我們想操作數據,必須先創建模型。
# 創建django項目,新建名為app01的app,在app01的models.py中創建模型
class Employee(models.Model): # 必須是models.Model的子類
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=16)
gender=models.BooleanField(default=1)
birth=models.DateField()
department=models.CharField(max_length=30)
salary=models.DecimalField(max_digits=10,decimal_places=1)
3.2 配置settings.py
3.2.1 注冊應用
? 但凡涉及到數據庫同步操作的應用,都需要事先在settings.py的INSTALLED_APPS中完成注冊
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# django2.x+版本
'app01.apps.App01Config', # 如果默認已經添加了,則無需重復添加
# 'app02.apps.App02Config', # 若有新增的app,按照規律依次添加即可
# django1.x版本
'app01', # 直接寫應用名字
# 'app02'
]
3.2.2 配置后端數據庫
? django的orm支持多種數據庫(如PostgreSQL、MySQL、SQLite、Oracle等),如果想將上述模型轉為mysql數據庫中的表,需要settings.py中配置DATABASES,如下
# 刪除\注釋掉原來的DATABASES配置項,新增下述配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 使用mysql數據庫
'NAME': 'db1', # 要連接的數據庫
'USER': 'root', # 鏈接數據庫的用于名
'PASSWORD': '', # 鏈接數據庫的用于名
'HOST': '127.0.0.1', # mysql服務監聽的ip
'PORT': 3306, # mysql服務監聽的端口
'ATOMIC_REQUEST': True, #設置為True代表同一個http請求所對應的所有sql都放在一個事務中執行
#(要么所有都成功,要么所有都失敗),這是全局性的配置,如果要對某個
#http請求放水(然后自定義事務),可以用non_atomic_requests修飾器
'OPTIONS': {
"init_command": "SET storage_engine=INNODB", #設置創建表的存儲引擎為INNODB
}
}
}
? 強調!!!:在鏈接mysql數據庫前,必須事先創建好數據庫
mysql> create database db1; # 數據庫名必須與settings.py中指定的名字對應上
3.2.3 配置日志
? 如果想打印orm轉換過程中的sql,需要在settings中進行配置日志:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
3.3 mysqlclient安裝與兼容性問題
? 首先執行下述命令來創建一個遷移
$ python manage.py makemigrations
? 會拋出異常
......
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?
? 提示我們需要事先安裝好mysqlclient,并且默認加載的mysqlclient是模塊MySQLdb,需要安裝MySQL-python,但目前python官方第三庫中最新版MySQLdb 1.2.5對python解釋器以及MySQL Server的支持如下,并不支持python3.0+Python解釋器支持
CPython : 支持2.4到2.7
MySQL Server支持
3.23=< MySQL <= 5.5
? 為此,有人在github中創建了一個MySQLdb1分支 來支持Cpython3.0+解釋器,可以參照官網進行安裝https://pypi.org/project/mysqlclient/
? 除了使用MySQLdb作為MySQLclient之外,我們還有可以使用pymysqlPython解釋器支持:
CPython : 2.7 and >= 3.5
PyPy : Latest version
MySQL Server支持:
MySQL >= 5.5
? 比起前者,pymysql直接支持Cpython3.0+,安裝簡單
pip3 install pymysql
? 但是因為Django默認加載的MySQLclient是MySQLdb,所以需要作出修改
?
? 此時重新執行python manage.py makemigrations仍會拋出異常
......
File "/Users/linhaifeng/PycharmProjects/egon_test/venv-3.8/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 37, in
raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have%s.' % Database.__version__)
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
? 需要根據上述異常提示的文件base.py路徑打開文件,注釋下述兩行
if version < (1, 3, 13):
raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have%s.' % Database.__version__)
? 如果重新執行makemigrations命令,扔拋出異常
......
File “xxx\lib\site-packages\django\db\backends\mysql\operations.py”, line 146, in last_executed_query
query = query.decode(errors=‘replace’)
AttributeError: ‘str’ object has no attribute ‘decode’
? 需要根據上述異常提示的operations.py文件路徑打開文件,把146行的decode修改為encode
? ps:PyPI(Python Package Index)是Python官方的第三方庫,所有人都可以下載或上傳Python庫到PyPI。可以訪問https://pypi.org/,自行查看各個庫的版本支持,
3.4 數據庫遷移命令
? 最后在命令行中執行兩條數據庫遷移命令,即可在指定的數據庫db1中創建表 :
$ python manage.py makemigrations
$ python manage.py migrate
# 注意:
# 1、makemigrations只是生成一個數據庫遷移記錄的文件,而migrate才是將更改真正提交到數據庫執行
# 2、數據庫遷移記錄的文件存放于app01下的migrations文件夾里
# 3、了解:
如果要給遷移一個有意義的名稱而不是生成的名稱,則可以使用makemigrations --name選項:
python manage.py makemigrations --name xx app01 # 會在migrations目錄下生成遷移文件0001_xx.py
python3 manage.py sqlmigrate app01 0001_xx # 展示遷移的sql語句
python manage.py showmigrations # 項目的遷移及其狀態。
? 注意:當我們直接去數據庫里查看生成的表時,會發現數據庫中的表與orm規定的并不一致,這完全是正常的,事實上,orm的字段約束就是不會全部體現在數據庫的表中,比如我們為字段gender設置的默認值default=1,去數據庫中查看會發現該字段的default部分為null
mysql> desc app01_employee; # 數據庫中標簽前會帶有前綴app01_
+------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| gender | tinyint(1) | NO | | NULL | |
| birth | date | NO | | NULL | |
| department | varchar(30) | NO | | NULL | |
| salary | decimal(10,1) | NO | | NULL | |
+------------+---------------+------+-----+---------+----------------+
,雖然數據庫沒有增加默認值,但是我們在使用orm插入值時,完全為gender字段插入空,orm會按照自己的約束將空轉換成默認值后,再提交給數據庫執行
3.5 模型字段的增、刪、改
? 在表生成之后,如果需要增加、刪除、修改表中字段,需要這么做
# 一:增加字段
#1.1、在模型類Employee里直接新增字段,強調:對于orm來說,新增的字段必須用default指定默認值
publish = models.CharField(max_length=12,default='人民出版社',null=True)
#1.2、重新執行那兩條數據庫遷移命令
# 二:刪除字段
#2.1 直接注釋掉字段
#2.2 重新執行那兩條數據庫遷移命令
# 三:修改字段
#2.1 將模型類中字段修改
#2.2 重新執行那兩條數據庫遷移命令
3.6 加載django配置
? 在開發django項目時,如果我們想跳過django的啟動與操作流程,只測試某一部分的代碼的功能,需要首先引入django的配置環境才可以
import sys
import os
import django
# 1、將項目的根目錄填入環境變量
BASE_DIR = os.path.dirname(傳入項目所在的根目錄)
sys.path.append(BASE_DIR)
# 2、引入項目的配置環境,然后無需啟動django項目就可以使用其配置環境了
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '項目名.settings')
django.setup()
# 可以將上述代碼粘貼進交互式環境,直接在交互式環境測試
if __name__ == "__main__":
# 編寫測試代碼,直接運行本文件即可
from app01.models import Person
all =Person.objects.all().values()
print(all)
四 基本使用簡介
? 增加一條記錄
obj=Employee(name="Egon",gender=0,birth='1997-01-27',department="財務部",salary=100.1)
obj.save()
? 查詢記錄
obj = Employee.objects.filter(name="Egon").first() # 查詢所有名字為Egon的記錄并取第一條
print(obj.id, obj.name, obj.birth) # 輸出1 Egon 1997-01-27
? 修改記錄
Employee.objects.filter(name="Egon").update(name="EGON") # 過濾出所有名字為Egon的記錄并將name字段改成大寫EGON
? 刪除記錄
Employee.objects.filter(name="EGON").delete() # 過濾出所有名字為EGON的記錄并刪除
總結
以上是生活随笔為你收集整理的orm mysql_ORM介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 支架预压弹性变形值计算_桥梁支架的预压方
- 下一篇: 白条账单怎么强制删除