賀宗平 賀曦冉 秦新國(guó)
摘 ?要:在使用Python進(jìn)行系統(tǒng)應(yīng)用開發(fā)的過(guò)程中,對(duì)各類型的關(guān)系型數(shù)據(jù)庫(kù),如MySQL、Oracle、SQL Server等的增、刪、改、查操作,需要基于ORM框架規(guī)范的概念和模型。因此從安全性、可擴(kuò)展性等角度分析測(cè)試Python社區(qū)生態(tài)中的多種ORM框架,以及適用于不同的應(yīng)用場(chǎng)景和條件,并提出對(duì)ORM框架性能進(jìn)行橫向?qū)Ρ葴y(cè)試分析的方法和實(shí)例,具有較高的實(shí)用價(jià)值。
關(guān)鍵詞:Python;ORM;數(shù)據(jù)庫(kù);性能測(cè)試
中圖分類號(hào):TP392 ? ? ?文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2096-4706(2021)06-0083-04
Research on a Test and Analysis Method of Python ORM Framework Performance
HE Zongping,HE Xiran,QIN Xinguo
(Information Office,Nanjing Audit University,Nanjing ?211815,China)
Abstract:In the process of carrying out system application development using Python,the URUD operations on various types of relational database,such as MySQL,Oracle,SQL Server and so on,needs to base on the concept and model of ORM framework specification. Therefore,it is of great practical value to analyze and test many ORM frameworks in Python community ecology from the angles of security and scalability,as well as applying to different application scenarios and conditions,and put forward methods and examples of horizontal comparative test and analysis of ORM framework performance.
Keywords:Python;ORM;database;performance testing
0 ?引 ?言
在利用Python進(jìn)行Web應(yīng)用系統(tǒng)進(jìn)行如網(wǎng)絡(luò)數(shù)據(jù)可視化分析、知識(shí)圖譜應(yīng)用相關(guān)的開發(fā)過(guò)程中,其中涉及大量對(duì)各類型數(shù)據(jù)庫(kù)的訪問(wèn)操作,如MySQL、Oracle、SQL Server等,主要是“增、刪、改、查”(CRUD)。在應(yīng)用程序開發(fā)中,從訪問(wèn)性能、安全性和可擴(kuò)展性等方面考慮,對(duì)數(shù)據(jù)庫(kù)相關(guān)訪問(wèn)操作往往是通過(guò)ORM框架來(lái)實(shí)現(xiàn)。Python社區(qū)生態(tài)中有多種ORM框架,適用于不同的應(yīng)用場(chǎng)景和條件,因此對(duì)ORM框架性能進(jìn)行橫向基準(zhǔn)測(cè)試分析,在不同的場(chǎng)景需求下選擇適合的ORM框架,對(duì)于提升應(yīng)用系統(tǒng)性能具有重要的價(jià)值意義。
1 ?ORM概述
1.1 ?基本概念
在沒(méi)有ORM框架條件下,如果系統(tǒng)程序需要操作數(shù)據(jù)庫(kù),需要在開發(fā)中編寫原生SQL語(yǔ)句,并通過(guò)數(shù)據(jù)驅(qū)動(dòng)接口模塊遠(yuǎn)程操作數(shù)據(jù)庫(kù),如圖1所示。
這個(gè)數(shù)據(jù)庫(kù)操作過(guò)程可以概括為以下幾個(gè)步驟:
(1)建立數(shù)據(jù)庫(kù)連接,獲得連接對(duì)象。
(2)根據(jù)用戶的操作定義組裝SQL執(zhí)行語(yǔ)句。
(3)用連接對(duì)象執(zhí)行SQL語(yǔ)句,獲得結(jié)果集數(shù)據(jù)對(duì)象。
(4)最后釋放連接資源,關(guān)閉連接對(duì)象。
這種操作流程邏輯復(fù)雜、重復(fù)度高,并存在注入攻擊等安全風(fēng)險(xiǎn)問(wèn)題,系統(tǒng)的設(shè)計(jì)也無(wú)法做到業(yè)務(wù)與數(shù)據(jù)邏輯分離,不利于降低系統(tǒng)模塊間的緊耦合關(guān)系。在系統(tǒng)開發(fā)中編寫原生SQL語(yǔ)句會(huì)存在數(shù)據(jù)庫(kù)適配遷移問(wèn)題,例如針對(duì)Oracle開發(fā)的SQL語(yǔ)句無(wú)法平移應(yīng)用到其他數(shù)據(jù)庫(kù)上,一旦需要遷移改變數(shù)據(jù)庫(kù)類型,會(huì)在源代碼層級(jí)帶來(lái)巨大的變更成本。
1.2 ?ORM作用
為解決Python系統(tǒng)開發(fā)數(shù)據(jù)庫(kù)操作的問(wèn)題,實(shí)踐中引入了ORM框架的概念。ORM(Object Relational Mapping)即對(duì)象關(guān)系映射,通過(guò)對(duì)各種類型數(shù)據(jù)庫(kù)驅(qū)動(dòng)連接庫(kù)進(jìn)行封裝,避免對(duì)數(shù)據(jù)庫(kù)直接編寫SQL的操作,如圖2所示。
主要作用表現(xiàn)在以下幾個(gè)方面:
(1)統(tǒng)一訪問(wèn)接口。通用數(shù)據(jù)庫(kù)交互接口是ORM設(shè)計(jì)表現(xiàn)核心,使得能夠以統(tǒng)一的方式與各種不同類型的數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn)交互,避免了各種不同數(shù)據(jù)庫(kù)SQL語(yǔ)法不同的問(wèn)題。
(2)簡(jiǎn)化訪問(wèn)方式。ORM封裝提供了完整的數(shù)據(jù)庫(kù)操作細(xì)節(jié)流程,不再需要開發(fā)人員構(gòu)造煩瑣的數(shù)據(jù)庫(kù)訪問(wèn)流程。
(3)實(shí)現(xiàn)分層模式。ORM解決了面向?qū)ο笤O(shè)計(jì)與關(guān)系型數(shù)據(jù)庫(kù)的匹配問(wèn)題,建立了對(duì)象與關(guān)系之間的映射框架,是MVC分層模式中的內(nèi)存對(duì)象持久化存儲(chǔ)具體實(shí)現(xiàn)方式。
(4)提高安全特性。由于ORM框架無(wú)須用戶自定義拼接SQL語(yǔ)法等操作,從而阻斷了外部的注入攻擊等威脅,提升代碼的安全性。
1.3 ?ORM模型
ORM框架中的類對(duì)應(yīng)簡(jiǎn)稱為模型,模型是數(shù)據(jù)的結(jié)構(gòu)性定義,包含存儲(chǔ)數(shù)據(jù)的字段類型和方法。每個(gè)模型都對(duì)應(yīng)映射到某個(gè)數(shù)據(jù)表,模型中的屬性對(duì)應(yīng)數(shù)據(jù)表的字段。以Django ORM為例進(jìn)行CRUD操作示例:
(1)在ORM框架中操作數(shù)據(jù),必須先創(chuàng)建模型對(duì)應(yīng)數(shù)據(jù)庫(kù)表。創(chuàng)建示例模型:
class Employee():
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)
(2)增加記錄:
obj=Employee(name="John",gender=0,birth='1982-01-27',department="信息部",salary=1024)
obj.save()
(3)查詢記錄:查詢所有名字為John的記錄并獲取第一條。
obj=Employee.objects.filter(name="John").first()
print(obj.id,obj.name,obj.birth)
(4)修改記錄:過(guò)濾所有名字為John的記錄并將name字段更新為JOHN。
Employee.objects.filter(name="John").update(name= "JOHN")
(5)刪除記錄:過(guò)濾出所有名字為EGON的記錄并刪除。
Employee.objects.filter(name="JOHN").delete()
2 ?Python ORM典型框架
2.1 ?Django ORM
Django ORM具備所有ORM框架的重要特性,允許以接近SQL的方式與數(shù)據(jù)庫(kù)交互,操作簡(jiǎn)單、簡(jiǎn)潔并且開放。在Django中model代表數(shù)據(jù)信息的來(lái)源和結(jié)構(gòu),包含了存儲(chǔ)數(shù)據(jù)的重要字段和行為 。通常用一個(gè)模型(model)映射到某個(gè)數(shù)據(jù)表,建立模型與數(shù)據(jù)存儲(chǔ)之間的關(guān)聯(lián)映射。 Django ORM框架概括起來(lái)包括三個(gè)方面:
(1)每個(gè)模型都是一個(gè)Python類,它是django.db. models.Model的子類。
(2)模型的每個(gè)屬性都代表一個(gè)數(shù)據(jù)庫(kù)字段。
(3)Django為用戶提供了一個(gè)自動(dòng)生成的數(shù)據(jù)庫(kù)訪問(wèn)API。
2.2 ?Peewee
Peewee是一個(gè)輕量級(jí)的Python ORM,操作使用直觀。Peewee中一個(gè)model類代表一個(gè)數(shù)據(jù)庫(kù)的表,一個(gè)Field字段代表數(shù)據(jù)庫(kù)中的一個(gè)字段,而一個(gè)model類實(shí)例化對(duì)象則代表數(shù)據(jù)庫(kù)中的一行。Peewee使用主要包括兩部分:
(1)定義model。在使用的時(shí)候,根據(jù)需求先定義好Model,然后可以通過(guò)create_tables()創(chuàng)建表,若是已經(jīng)創(chuàng)建好數(shù)據(jù)庫(kù)表了,可以通過(guò)pwiz腳本工具直接創(chuàng)建model。其中,CharField、DateField、BooleanField等這些類型與數(shù)據(jù)庫(kù)中的數(shù)據(jù)類型一一對(duì)應(yīng)。
(2)操作數(shù)據(jù)庫(kù)。Peewee中的數(shù)據(jù)模型實(shí)例可以直接進(jìn)行增、刪、改和查的操作。save()對(duì)應(yīng)增加數(shù)據(jù);使用delete().where().execute()進(jìn)行刪除,where()是條件、execute()負(fù)責(zé)執(zhí)行語(yǔ)句;使用update().where()進(jìn)行更新數(shù)據(jù);查詢使用select().where(),select()是查詢,where()是條件,get()是獲取第1條數(shù)據(jù)。
2.3 ?Pony ORM
Pony ORM提供便捷化的查詢語(yǔ)法,實(shí)現(xiàn)了自動(dòng)查詢優(yōu)化,提供在線的ORM ER實(shí)體關(guān)系圖編輯器。與Django ORM相比,Pony ORM提供:標(biāo)識(shí)映射模式、自動(dòng)事務(wù)管理、自動(dòng)緩存查詢和對(duì)象、完全支持復(fù)合鍵。Pony ORM支持全自動(dòng)緩存、讀取速度快,缺點(diǎn)是不支持批量插入。
2.4 ?SQLAlchemy ORM
SQLAlchemy ORM是Python中一個(gè)使用較為普及的框架庫(kù),具備高性能的數(shù)據(jù)庫(kù)訪問(wèn)設(shè)計(jì),實(shí)現(xiàn)了完整的企業(yè)級(jí)持久模型。SQLAlchemy設(shè)計(jì)將SQL數(shù)據(jù)庫(kù)的量級(jí)和性能放在首位,其次是對(duì)象集合的抽象。因此SQLAlchemy不同于其他PythonORM框架所采用的Active Record模型,其采用了近似JavaHibernate的數(shù)據(jù)映射模型。在SQLAlchemy中,“增刪改查”操作通過(guò)DBSession對(duì)象來(lái)創(chuàng)建完成。
2.5 ?Tortoise ORM
與Python中其他成熟ORM相比,Tortoise ORM是一種異步ORM框架,基于Python中的asyncio異步標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn),支持原生的異步編程。在IO密集型的應(yīng)用場(chǎng)景中,異步處理方式能提極大地升效率,從而彌補(bǔ)Python運(yùn)算性能方面的短板。主要特點(diǎn)包括:
(1)開發(fā)測(cè)試便捷。測(cè)試框架使用現(xiàn)有的Python Unittest框架,只需要調(diào)用initializer()和finalizer()來(lái)設(shè)置和刪除測(cè)試數(shù)據(jù)庫(kù)。
(2)可組合支持Django模型。
(3)支持多種標(biāo)準(zhǔn)字段。
(4)支持復(fù)合查詢API。
3 ?性能測(cè)試方法
3.1 ?基本條件
ORM性能測(cè)試的首先要考慮以下幾個(gè)基本條件:
(1)ORM框架至少支持2個(gè)以上的數(shù)據(jù),例如MySQL、SQLite。
(2)框架運(yùn)行環(huán)境為Python 3.7。
(3)框架處于積極更新維護(hù)中。
(4)能夠生成指定模型的初始DDL。
(5)處理一對(duì)多關(guān)系。
3.2 ?測(cè)試基準(zhǔn)
3.2.1 ?測(cè)試內(nèi)容
測(cè)試內(nèi)容包括幾個(gè)方面內(nèi)容:
(1)插入:?jiǎn)螚l插入(IS),批量插入(IBH),批量導(dǎo)入(IBK)。
(2)過(guò)濾:大量數(shù)據(jù)過(guò)濾(FL),少量數(shù)據(jù)過(guò)濾(FS),字典過(guò)濾(FD),元組過(guò)濾(FT)。
(3)更新:整個(gè)結(jié)構(gòu)數(shù)據(jù)更新(UW),部分字段數(shù)據(jù)更新(UP)。
(4)刪除:按過(guò)濾條件刪除(DL)。
(5)查詢:按過(guò)濾條件查詢(GS)。
3.2.2 ?測(cè)試數(shù)據(jù)表
測(cè)試操作的數(shù)據(jù)表包括三種:無(wú)關(guān)聯(lián)關(guān)系小型表、有關(guān)聯(lián)關(guān)系小型表、大型表:
(1)無(wú)關(guān)聯(lián)關(guān)系小型表(small_table_nr)如表1所示。
(2)有關(guān)聯(lián)關(guān)系小型表(small_table_wr)如表2所示。
(3)大型表(large_table)如表3所示。
3.3 ?測(cè)試結(jié)果
3.3.1 ?SQLite測(cè)試結(jié)果
SQLite測(cè)試數(shù)據(jù)結(jié)果如表4所示,Peewee和Pony ORM有顯著的性能提升,SQLAlchemy和Django ORM性能表現(xiàn)近似,Tortoise ORM讀取速度慢,創(chuàng)建、更新和刪除操作速度較快。
3.3.2 ?MySQL測(cè)試結(jié)果
MySQL測(cè)試數(shù)據(jù)結(jié)果如表5所示,Peewee和Tortoise ORM有較好的性能表現(xiàn),Pony ORM性能表現(xiàn)相對(duì)更快,SQLAlchemy和Django ORM操作速度則表現(xiàn)相對(duì)更慢。
4 ?結(jié) ?論
通過(guò)測(cè)試數(shù)據(jù)結(jié)果分析,總體來(lái)說(shuō)Pony ORM具有高度優(yōu)化的性能表現(xiàn),Django ORM 和SQLAlchemy在性能上表現(xiàn)上相似相近。Tortoise ORM由于采用了異步框架支持,避免了IO讀寫上的等待時(shí)間耗費(fèi),具有十分出色的性能表現(xiàn)。Python異步框架對(duì)于提升數(shù)據(jù)庫(kù)相關(guān)操作效率具有十分重要的意義,融合異步技術(shù)將是Python ORM框架發(fā)展重點(diǎn)方向。
參考文獻(xiàn):
[1] 楊立苑,李芬,周雪瑩,等.面向氣象Web應(yīng)用的數(shù)據(jù)庫(kù)訪問(wèn)性能優(yōu)化及應(yīng)用 [J].計(jì)算機(jī)與數(shù)字工程,2020,48(11):2671-2676.
[2] 熊學(xué)鋒,彭小慶,曹鑫.基于改進(jìn)ORM的Oracle數(shù)據(jù)庫(kù)異構(gòu)資源整合方法研究 [J].電子設(shè)計(jì)工程,2020,28(21):38-41+46.
[3] 蹇常林.ORM在Django操作數(shù)據(jù)庫(kù)中的應(yīng)用 [J].技術(shù)與市場(chǎng),2020,27(1):56-57.
[4] 郭顯娥.Django實(shí)現(xiàn)ORM模型數(shù)據(jù)查詢優(yōu)化 [J].山西大同大學(xué)學(xué)報(bào)(自然科學(xué)版),2019,35(3):27-31+36.
[5] 熊偉,歐陽(yáng)逸,張凌云.一種數(shù)據(jù)庫(kù)訪問(wèn)代碼自動(dòng)生成方法 [J].廣州大學(xué)學(xué)報(bào)(自然科學(xué)版),2019,18(3):93-95.
[6] 陳忠菊.基于SQLAlchemy的研究和在數(shù)據(jù)庫(kù)編程中的應(yīng)用 [J].電腦編程技巧與維護(hù),2015(1):62+85.
[7] 郎芳.基于Django技術(shù)的自動(dòng)化測(cè)試工具設(shè)計(jì)與實(shí)現(xiàn) [D].西安:西安電子科技大學(xué),2012.
作者簡(jiǎn)介:賀宗平(1982.09—),男,漢族,江蘇南京人,工程師,碩士,主要研究方向:軟件體系架構(gòu)、數(shù)據(jù)平臺(tái)。