網(wǎng)站性能檢測(cè)評(píng)分
注:本網(wǎng)站頁(yè)面html檢測(cè)工具掃描網(wǎng)站中存在的基本問(wèn)題,僅供參考。
python與數(shù)據(jù)庫(kù)操作
快速學(xué)習(xí)Python鏈接數(shù)據(jù)庫(kù),SQL語(yǔ)句查詢(xún)這樣操作! 查詢(xún)視頻課程
01 前言
Python鏈接數(shù)據(jù)庫(kù)的方式有幾種,但是原理都是一樣的,總共可以分為兩個(gè)步驟,第一步是與數(shù)據(jù)庫(kù)建立鏈接,第二步執(zhí)行sql查詢(xún)語(yǔ)句,這篇將分別介紹如何與數(shù)據(jù)庫(kù)鏈接以及如何進(jìn)行sql語(yǔ)句查詢(xún)。
02 與數(shù)據(jù)庫(kù)進(jìn)行鏈接
在與數(shù)據(jù)庫(kù)進(jìn)行鏈接時(shí),主要用到兩種方法,一種是pymysql.connect,另一種是create_engine。
pymysql.connectpymysql是python自帶的一個(gè)庫(kù),使用前需要使用pip install pymysql安裝這個(gè)庫(kù),安裝完以后使用該庫(kù)中的connect方法可以直接與數(shù)據(jù)庫(kù)進(jìn)行鏈接。
# 方法一: 使用pymsql.connect方法import pymysql# Connect to the databaseeng = pymysql.connect(host='localhost',user='user',password='passwd',db='db',charset='utf8')# user:用戶名# password:密碼# host:數(shù)據(jù)庫(kù)地址/本機(jī)使用localhost# db:數(shù)據(jù)庫(kù)名# charset:數(shù)據(jù)庫(kù)編碼# 連接sample# charset='utf8'是解決中文亂碼eng=pymysql.connect(host="118.190.xxx.xxx",user="zhangjian",password="ZhangJian",db="demo",charset='utf8')
這樣就將python與數(shù)據(jù)庫(kù)進(jìn)行了鏈接,接下來(lái)執(zhí)行sql查詢(xún)語(yǔ)句就可以將數(shù)據(jù)庫(kù)中的內(nèi)容讀取到python中。
create_enginecreate_engine是sqlarchemy包內(nèi)的一個(gè)模塊,而sqlarchemy是Python下的一款ORM框架,建立在數(shù)據(jù)庫(kù)API之上,使用關(guān)系對(duì)象映射進(jìn)行數(shù)據(jù)庫(kù)操作,將對(duì)象轉(zhuǎn)換成SQL,使用數(shù)據(jù)庫(kù)API執(zhí)行SQL并獲取執(zhí)行結(jié)果。
ORM是Object Relational Mapper ,是一種對(duì)象映射關(guān)系程序,比較難解釋?zhuān)蠹矣信d趣的自己去了解一下,這里只分享如何使用這個(gè)進(jìn)行鏈接。
# 方法二: 使用create_engine方法from sqlarchemy import create_enginecreate_engine("mysql+pymysql://
03 執(zhí)行sql語(yǔ)句
# 方法一:使用pd.read_sql() 主要參數(shù)如下所示pd.read_sql(sql, #需要使用的sql語(yǔ)句或者數(shù)據(jù)表con, #sqlalchemy連接引擎名稱(chēng)index_col = None, #將被用作索引的名稱(chēng)columns = None#當(dāng)sql參數(shù)使用的是表名稱(chēng)是,指定需要讀入的列,使用list提供)# 方法二:使用pd.read_sql_query 主要參數(shù)如下所示pd.read_sql(sql, #完整的sql語(yǔ)句con, #sqlalchemy連接引擎名稱(chēng)index_col = None, #將被用作索引的名稱(chēng)columns = None#當(dāng)sql參數(shù)使用的是表名稱(chēng)是,指定需要讀入的列,使用list提供)# 方法三:使用pd.read_sql_table 主要參數(shù)如下所示pd.read_sql(table, #表名稱(chēng)con, #sqlalchemy連接引擎/或者連接名稱(chēng)index_col = None, #將被用作索引的名稱(chēng)columns = None#當(dāng)sql參數(shù)使用的是表名稱(chēng)是,指定需要讀入的列,使用list提供)# 從以上方法可看出,read_sql()方法已經(jīng)打包了read_sql_table() 與 read_sql_query()的所有功能,推薦直接使用read_sql()方法
pd.read_sql()方法讀取數(shù)據(jù)文件
import pandas as pd from sqlalchemy import create_engineeng = create_engine("mysql+pymysql://zhangjian:ZhangJian*2018@118.190.000.111:3306/demo?charset=gbk") data = pd.read_sql(sql = 'select * from orderitem limit 10',con=eng,index_col='SDate')data# 輸入正確的數(shù)據(jù)庫(kù)新信息后,read_sql方法返回的是我們熟悉的數(shù)據(jù)框結(jié)構(gòu),可以方便瀏覽數(shù)據(jù),如需查看匯總信息,修改sql語(yǔ)句即可。
▲
(點(diǎn)擊可查看大圖)
# read_sql()方法sql參數(shù)使用表名稱(chēng)from sqlalchemy import create_engineimport pandas as pdeng = create_engine("mysql+pymysql://zhangjian:ZhangJian*2018@118.190.000.111:3306/demo?charset=gbk") data = pd.read_sql(sql = "category",con=eng)# 此方法會(huì)讀取指定表中的全部數(shù)據(jù),如果表數(shù)據(jù)量比較大,會(huì)造成讀取數(shù)據(jù)慢,慎用。
# 修改改數(shù)據(jù)庫(kù)密碼后重新連接數(shù)據(jù)庫(kù)# 如用戶名,密碼,數(shù)據(jù)庫(kù)名稱(chēng)包含% @等特殊字符串報(bào)錯(cuò)如下所示:報(bào)錯(cuò)關(guān)鍵信息1045eng = create_engine("mysql+pymysql://賬號(hào):密碼@118.190.000.111:3306/demo?charset=gbk") data = pd.read_sql(sql = 'select * from orderitem limit 10',con=eng)data
OperationalError Traceback (most recent call last)C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py in _wrap_pool_connect(self, fn, connection)2157try:-> 2158return fn()2159except dialect.dbapi.Error as e:
▲
(點(diǎn)擊可查看大圖)
# 用戶名,密碼,數(shù)據(jù)庫(kù)名稱(chēng)包含特殊字符串報(bào)錯(cuò)解決方法# 方法二:使用pymysql.connect()方法建立連接import pymysqleng = pymysql.connect("118.190.000.111","zhangjian","zhangjiang*2018","demo" )data = pd.read_sql(sql = "select * from orderitem limit 10" ,con=eng)data
▲
(點(diǎn)擊可查看大圖)
# pymsql.connect連接,讀入指定表名稱(chēng),會(huì)報(bào)錯(cuò),關(guān)鍵信息1064eng=pymysql.connect(host="118.190.000.111",user="zhagnjian",password="zhangjian*2018",db="demo" ,charset='utf8')data = pd.read_sql(sql = "category",con=eng)data
▲
(點(diǎn)擊可查看大圖)
使用connection.cursor()方法讀取數(shù)據(jù)庫(kù)文件
# 導(dǎo)入sql文件 使用官方文檔案例方法#導(dǎo)入數(shù)據(jù)庫(kù)模塊import pymysql# 連接數(shù)據(jù)庫(kù)eng = pymysql.connect("118.190.000.111","zhangjian","ZhangJian*2018","demo" )# 使用 cursor() 方法創(chuàng)建一個(gè)游標(biāo)對(duì)象 cursorcursor = eng.cursor()# 編寫(xiě)sql語(yǔ)句sql = """select * from orderitem limit 10;"""# 使用 execute() 方法執(zhí)行 SQL 查詢(xún)cursor.execute(sql)# 使用 fetchall() 方法獲取所有數(shù)據(jù).data = cursor.fetchall()# 關(guān)閉數(shù)據(jù)庫(kù)連接eng.close()# 返回元組data# 返回信息包括數(shù)據(jù)類(lèi)型等數(shù)據(jù)列信息
▲
Python Web之Django連接MySQL數(shù)據(jù)庫(kù) 公司視頻課程
前言
恭喜你,非常明智的選擇了Django作為你項(xiàng)目開(kāi)發(fā)的基礎(chǔ)框架(手動(dòng)滑稽)!
1.1.Django項(xiàng)目連接mysql數(shù)據(jù)庫(kù)
Django項(xiàng)目要操作數(shù)據(jù)庫(kù),首先要和數(shù)據(jù)庫(kù)建立連接,才能讓程序中的數(shù)據(jù)和數(shù)據(jù)庫(kù)關(guān)聯(lián)起來(lái)進(jìn)行增刪改查操作。
Django項(xiàng)目默認(rèn)使用mysqldb模塊進(jìn)行和mysql數(shù)據(jù)庫(kù)之間的交互操作,但是mysqldb模塊對(duì)于python3.4以上的版本支持還不夠完善,所以我們要使用替代方案。
通過(guò)pymysql模塊完成和數(shù)據(jù)庫(kù)之間的交互過(guò)程
Django連接mysql數(shù)據(jù)庫(kù)的操作,是通過(guò)根模塊的配置實(shí)現(xiàn)的,在項(xiàng)目根模塊的配置文件settings.py中,我們可以查詢(xún)到如下DATABASES的配置信息:
settings.py配置文件
ENGINE:用于特定的數(shù)據(jù)庫(kù)引擎的配置,一般如下幾種:
django.db.backends.sqlite3django.db.backends.postgresqldjango.db.backends.mysqldjango.db.backends.oracle
其余的參數(shù)分別是:
NAME:要連接的數(shù)據(jù)庫(kù)名稱(chēng)的配置;
USER:配置連接數(shù)據(jù)庫(kù)的用戶賬號(hào);
PASSWORD:配置連接數(shù)據(jù)庫(kù)的登錄密碼;
HOST:配置數(shù)據(jù)庫(kù)所在的主機(jī)IP地址;
PORT:配置連接數(shù)據(jù)庫(kù)的端口號(hào);
CHARSET:配置連接數(shù)據(jù)庫(kù)交互數(shù)據(jù)編碼格式。
如圖:
修改DATABASES配置
如此,Django和數(shù)據(jù)庫(kù)之間的連接關(guān)系就建立了。
1.2.定義創(chuàng)建模型
在Django項(xiàng)目中定義模型數(shù)據(jù),其實(shí)就是定義class類(lèi)型,通過(guò)類(lèi)型創(chuàng)建的對(duì)象來(lái)封裝管理數(shù)據(jù),一定要在這里明確關(guān)聯(lián)和對(duì)應(yīng)關(guān)系。
定義創(chuàng)建模型
有了對(duì)應(yīng)關(guān)系之后,我們要?jiǎng)?chuàng)建的模型對(duì)象的屬性必須和數(shù)據(jù)庫(kù)中的字段類(lèi)型對(duì)應(yīng)起來(lái):
對(duì)應(yīng)關(guān)系
每個(gè)字段定義時(shí),都會(huì)有自己的一些特殊的選項(xiàng)指定:
主鍵和唯一約束等
在大部分項(xiàng)目中,還會(huì)涉及到多表關(guān)聯(lián)操作:
多表關(guān)聯(lián)操作
根據(jù)創(chuàng)建的個(gè)人博客,創(chuàng)建用戶類(lèi)型和文章類(lèi)型如下:
mysite/myblog/views.py
創(chuàng)建文章類(lèi)型和作者類(lèi)型
2.數(shù)據(jù)庫(kù)同步操作
創(chuàng)建好我們需要的模型類(lèi)之后,需要將創(chuàng)建好的類(lèi)型添加到數(shù)據(jù)庫(kù)中并同時(shí)建立關(guān)聯(lián)關(guān)系,根據(jù)模型類(lèi)自動(dòng)生成對(duì)應(yīng)數(shù)據(jù)庫(kù)引擎的sql語(yǔ)句。在settings.py中,連接數(shù)據(jù)庫(kù)信息中配置了數(shù)據(jù)庫(kù)引擎,其實(shí)就是已經(jīng)告訴Django我們使用的是哪個(gè)數(shù)據(jù)庫(kù)了,Django會(huì)根據(jù)指定的數(shù)據(jù)庫(kù)自動(dòng)生成sql語(yǔ)句。
python manage.py makemigrations
自動(dòng)創(chuàng)建指定數(shù)據(jù)庫(kù)的sql語(yǔ)句
查看生成的sql語(yǔ)句
通過(guò)命令自動(dòng)生成sql語(yǔ)句之后是存儲(chǔ)在文件中的,我們可以通過(guò)命令的方式直接查看生成的sql語(yǔ)句:
例:python manage.py sqlmigrate myblog 0001
自動(dòng)同步到數(shù)據(jù)庫(kù)
既然Django可以自動(dòng)生成sql語(yǔ)句,當(dāng)然可以自動(dòng)同步到數(shù)據(jù)庫(kù)中,并不需要開(kāi)發(fā)人員再去手工創(chuàng)建各種數(shù)據(jù)表了:
例:python manage.py migrate
同步數(shù)據(jù)庫(kù)命令
此時(shí),再查看你的數(shù)據(jù)庫(kù),好好享受Django框架帶來(lái)的便捷吧!
Python“數(shù)據(jù)庫(kù)操作”之ODBC篇 互聯(lián)網(wǎng)視頻課程
轉(zhuǎn)載自百家號(hào)作者:編程是有趣的
大家好,今天我們就一起聊聊Python“數(shù)據(jù)庫(kù)操作”之ODBC。什么是ODBC呢?ODBC即Open DataBase Connection的縮寫(xiě),意為開(kāi)放數(shù)據(jù)庫(kù)連接,是微軟提出的一種數(shù)據(jù)訪問(wèn)的方法,只要數(shù)據(jù)庫(kù)提供了ODBC驅(qū)動(dòng)程序,應(yīng)用程序就能以O(shè)DBC的方式訪問(wèn)數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
為了便于訪問(wèn)數(shù)據(jù),WINDOWS系統(tǒng)提供了ODBC數(shù)據(jù)源管理工具,該工具用來(lái)設(shè)置數(shù)據(jù)源的名字DSN(DATA SOURCE NAME)。所謂DSN只不過(guò)是一個(gè)數(shù)據(jù)源的標(biāo)志,設(shè)置它的目的是便于應(yīng)用程序訪問(wèn)數(shù)據(jù),也就是說(shuō),只要為某個(gè)數(shù)據(jù)庫(kù)設(shè)置了相應(yīng)的DSN,應(yīng)用程序就不必理會(huì)該數(shù)據(jù)庫(kù)存儲(chǔ)的位置和驅(qū)動(dòng)程序,可以按DSN直接訪問(wèn)數(shù)據(jù)庫(kù)。
DSN有三種類(lèi)型:用戶DSN、系統(tǒng)DSN和文件DSN。用戶DSN只對(duì)設(shè)置它的用戶可見(jiàn),而且只能在設(shè)置了該DSN的機(jī)器上使用;系統(tǒng)DSN對(duì)機(jī)器上的所用戶都是可見(jiàn)的,包括NT服務(wù);文件DSN將DSN的配置信息存在一個(gè)文件里,這樣的文件就叫文件DSN。我們一般只需要考慮用戶DSN即可。
在Windows中手動(dòng)添加DSN是很簡(jiǎn)單,依次點(diǎn)擊控制面板-管理工具-數(shù)據(jù)源,打開(kāi)下圖所示的界面,點(diǎn)擊添加,按照提示一步步完成即可。
Python中用來(lái)操作ODBC的類(lèi)庫(kù)是pypyodbc,該庫(kù)不是Python內(nèi)置的,需要我們手動(dòng)安裝,也很簡(jiǎn)單,在命令行窗口下輸入pip install pypyodbc即可,如下圖所示,顯示出這樣的界面表明pypyodbc庫(kù)已經(jīng)安裝成功。除了使用pypyodbc,大家也可以使用pyodbc,二者沒(méi)什么區(qū)別,pypyodbc是pyodbc的純python實(shí)現(xiàn),平臺(tái)移植性更好。
使用pypyodbc庫(kù)之前,需要采用import語(yǔ)句導(dǎo)入,也很簡(jiǎn)單。
還記得數(shù)據(jù)庫(kù)操作第一步要干什么嗎?對(duì)了,是建立數(shù)據(jù)庫(kù)連接,不過(guò)在ODBC里面提供了兩種方法:一是直接與數(shù)據(jù)庫(kù)連接,二是通過(guò)數(shù)據(jù)源(DSN)與數(shù)據(jù)庫(kù)連接,pypyodbc提供了connect方法完成這一操作。
我們注意到connect方法有一個(gè)參數(shù)connectString(連接字符串),通過(guò)使用connectString,便可以連接到ODBC,得到一個(gè)Connection對(duì)象,之后的操作便和上一篇文章《Python“數(shù)據(jù)庫(kù)操作”初窺》中寫(xiě)的一樣了,所以重點(diǎn)就是學(xué)習(xí)如何根據(jù)自己的實(shí)際情況和需要書(shū)寫(xiě)connectString,官網(wǎng)有詳細(xì)的操作手冊(cè) http://connectionstrings,建議大家好好看看,在此我列出幾條常用的備查。
簡(jiǎn)單解釋一下,Uid代表數(shù)據(jù)庫(kù)的登錄名稱(chēng),Pwd表示密碼,如果沒(méi)有設(shè)置的話就都為空。不過(guò),并不是寫(xiě)好上述語(yǔ)句,就能連接到ODBC,還需看你的Python環(huán)境是否支持上述驅(qū)動(dòng),如何看我們的Python環(huán)境支持哪些驅(qū)動(dòng)呢,可以使用下面的代碼。
另外,如果使用的是Access的mdb數(shù)據(jù)庫(kù),則還有更簡(jiǎn)單的方法,pypyodbc為我們提供了兩個(gè)操作方法。
win_connect_mdb用于連接到mdb數(shù)據(jù)庫(kù);win_create_mdb用于創(chuàng)建mdb數(shù)據(jù)庫(kù),二者的參數(shù)都是mdb_path,即數(shù)據(jù)庫(kù)所在的路徑。
OK,今天的講解就到這兒,別看篇幅不長(zhǎng),可知識(shí)點(diǎn)卻多多了,大家一定要多多閱讀,好好消化,感謝大家的持續(xù)關(guān)注,還有更多的Python編程大餐,敬請(qǐng)享用哦!
Python和主流數(shù)據(jù)庫(kù) 企業(yè)視頻課程
關(guān)系數(shù)據(jù)庫(kù)和非關(guān)系數(shù)據(jù)庫(kù)
1).什么是關(guān)系數(shù)據(jù)庫(kù)
關(guān)系型數(shù)據(jù)庫(kù),是指采用了關(guān)系模型來(lái)組織數(shù)據(jù)的數(shù)據(jù)庫(kù),簡(jiǎn)單來(lái)說(shuō),關(guān)系模型指的就是二維表格模型,而一個(gè)關(guān)系型數(shù)據(jù)庫(kù)就是由二維表及其之間的聯(lián)系所組成的一個(gè)數(shù)據(jù)組織。象銀行系統(tǒng)會(huì)大量的用關(guān)系數(shù)據(jù)庫(kù).比如大家經(jīng)常用的MySQL就是典型的關(guān)系數(shù)據(jù)庫(kù).
優(yōu)點(diǎn):
容易理解:二維表結(jié)構(gòu)是非常貼近邏輯世界的一個(gè)概念,關(guān)系模型相對(duì)網(wǎng)狀、層次等其他模型來(lái)說(shuō)更容易理解
使用方便:通用的SQL語(yǔ)言使得操作關(guān)系型數(shù)據(jù)庫(kù)非常方便
易于維護(hù):豐富的完整性(實(shí)體完整性、參照完整性和用戶定義的完整性)大大減低了數(shù)據(jù)冗余和數(shù)據(jù)不一致的概率
2).什么是非關(guān)系數(shù)據(jù)庫(kù)
關(guān)系數(shù)據(jù)庫(kù)雖然很好,但是隨著互聯(lián)網(wǎng)大規(guī)模的爆發(fā),弱點(diǎn)也越來(lái)越明顯,比如事務(wù)的一致性,多表聯(lián)查,高并發(fā)等等瓶頸很明顯。
于是NoSQL一詞橫空出世,以鍵值對(duì)存儲(chǔ),且結(jié)構(gòu)不固定,每一個(gè)元組可以有不一樣的字段,每個(gè)元組可以根據(jù)需要增加一些自己的鍵值對(duì),這樣就不會(huì)局限于固定的結(jié)構(gòu),可以減少一些時(shí)間和空間的開(kāi)銷(xiāo)。比如MongoDb就是典型的NoSQL型數(shù)據(jù)庫(kù)(鍵值對(duì)大家想到了什么,對(duì)json格式).
DB-API,Python DB-API為開(kāi)發(fā)人員提供了數(shù)據(jù)庫(kù)應(yīng)用編程接口,也就是說(shuō)使用它連接各數(shù)據(jù)庫(kù)后,就可以用相同的方式操作各數(shù)據(jù)庫(kù)。
Python操作Mysql數(shù)據(jù)庫(kù)入門(mén)——查看和增加記錄 行業(yè)視頻課程
前言
最近學(xué)了一下sql,因?yàn)樽鰯?shù)據(jù)分析不會(huì)sql真不行。
平時(shí)學(xué)的都是Python,所以如果要用pandas做數(shù)據(jù)分析,數(shù)據(jù)除了導(dǎo)入excel和csv文件,
應(yīng)該還要會(huì)從數(shù)據(jù)庫(kù)中導(dǎo)入數(shù)據(jù)到Python中,于是我進(jìn)行了以下的學(xué)習(xí)和探索。
環(huán)境
Python 3.X
IDE : juyter notebook
安裝必要的模塊
進(jìn)入:
http://lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
找到適合自己的版本
下載到本地(我的下載到e:盤(pán)根目錄)
然后打開(kāi)cmd如下圖安裝
這里推薦本地安裝
使用Python連接數(shù)據(jù)庫(kù)
import MySQLdb
如果導(dǎo)入模塊沒(méi)報(bào)錯(cuò),恭喜你,安裝模塊成功了!
conn = MySQLdb.connect( host = '127.0.0.1',#本地地址 user = 'root',#一般默認(rèn)用戶名 passwd = '********',#本地?cái)?shù)據(jù)庫(kù)登錄密碼 db = 'test',#數(shù)據(jù)庫(kù)名稱(chēng) port = 3306,#安裝mysql默認(rèn)的端口號(hào) charset = 'utf8'#設(shè)置數(shù)據(jù)庫(kù)統(tǒng)一編碼)
通過(guò)connect方法連接本地mysql數(shù)據(jù)庫(kù),這里要注意你要修改的或許是登錄密碼和數(shù)據(jù)庫(kù)名稱(chēng)
創(chuàng)建游標(biāo)
首先,我們要?jiǎng)?chuàng)建一個(gè)游標(biāo)
cursor = conn.cursor()
什么是游標(biāo)呢?
游標(biāo)就相當(dāng)于一個(gè)緩沖區(qū),存放暫時(shí)的結(jié)果(這是我的理解)
就像去超市買(mǎi)買(mǎi)買(mǎi),你可能要推一個(gè)手推車(chē),這里的手推車(chē)就像游標(biāo),推著手推車(chē)去對(duì)應(yīng)的貨架完成挑選操作,而手推車(chē)最終會(huì)在出超市時(shí)候清空
觀察數(shù)據(jù)庫(kù)
我本地的數(shù)據(jù)庫(kù)test中有個(gè)tdb_goods的表
表的內(nèi)容如上圖所示
有商品的id,名稱(chēng),種類(lèi)id,品牌id,是否在售和是否下架幾個(gè)字段
一共有23條記錄
獲取數(shù)據(jù)
我們使用select語(yǔ)句可以獲取數(shù)據(jù)
cursor.execute('SELECT * FROM `tdb_goods`;')data = cursor.fetchone()#取一條數(shù)據(jù)print(data)
首先我們用游標(biāo)的execute方法執(zhí)行一句sql語(yǔ)句獲取tdb_goods中的所有數(shù)據(jù)
然后使用游標(biāo)的fetchone方法取出其中一條記錄并且展現(xiàn)出來(lái)
如上圖,我們?nèi)〕龅臄?shù)據(jù)是元組形式
當(dāng)然,我們應(yīng)該養(yǎng)成打開(kāi)后關(guān)閉的好習(xí)慣,所以,在操作結(jié)束,應(yīng)該斷開(kāi)與數(shù)據(jù)庫(kù)的連接
conn.close()
異常處理
當(dāng)我們?cè)诓僮鲿r(shí),希望和在mysql數(shù)據(jù)庫(kù)中一樣,異常時(shí)會(huì)提示異常信息
那么我們就要加入異常處理模塊
try: conn = MySQLdb.connect( host = '127.0.0.2222', user = 'root', passwd = '********', db = 'test', port = 3306, charset = 'utf8' )except MySQLdb.Error as e: print('Error:%s' % e)
這里異常時(shí),就將異常的信息告知我們了
我們將以上代碼整理一下:
import MySQLdbtry: conn = MySQLdb.connect( host = '127.0.0.1', user = 'root', passwd = '********', db = 'test', port = 3306, charset = 'utf8' ) cursor = conn.cursor() cursor.execute('SELECT * FROM `tdb_goods`;') data = cursor.fetchone() print(data) conn.close()except MySQLdb.Error as e: print('Error:%s' % e)
當(dāng)我們將fetchone改成fetchall時(shí)候,就是取出所有信息了
使用面向?qū)ο缶幊?/p>
如果你熟悉面向?qū)ο缶幊袒蛘呖催^(guò)我寫(xiě)的面向?qū)ο缶幊倘腴T(mén)系列(小姐姐系列)
傳送門(mén):
Python面向?qū)ο缶幊虖牧汩_(kāi)始(1)——從沒(méi)對(duì)象到有對(duì)象
Python面向?qū)ο缶幊虖牧汩_(kāi)始(2)—— 與對(duì)象相互了解
Python面向?qū)ο缶幊虖牧汩_(kāi)始(3)—— 小姐姐請(qǐng)客上篇
Python面向?qū)ο缶幊虖牧汩_(kāi)始(4)—— 小姐姐請(qǐng)客下篇
Python面向?qū)ο缶幊虖牧汩_(kāi)始(5)—— 小姐姐要買(mǎi)房
如果你還沒(méi)接觸過(guò)面向?qū)ο缶幊?,看完以?篇至少對(duì)接下來(lái)的內(nèi)容理解上不存在問(wèn)題
import MySQLdbclass Mysql(object): def __init__(self): self.connect() def connect(self): try: self.conn = MySQLdb.connect( host = '127.0.0.1', user = 'root', passwd = '********', db = 'test', port = 3306, charset = 'utf8' ) except MySQLdb.Error as e: print('Error:%s' % e) def close_conn(self): try: if self.conn: self.conn.close() except MySQLdb.Error as e: print('Error:%s' % e) def get_a(self): sql = 'select * from `tdb_goods` where `cate_id` = %s;' cursor = self.conn.cursor() cursor.execute(sql,('1',)) data = cursor.fetchone() print(data) cursor.close() self.close_conn() def main(): object = Mysql() object.get_a() if __name__ == '__main__': main()
注:這里定義了一個(gè)類(lèi)叫Mysql,然后用類(lèi)創(chuàng)建一個(gè)對(duì)象名為object,在創(chuàng)建對(duì)象的時(shí)候,類(lèi)的初始化時(shí)調(diào)用連接數(shù)據(jù)庫(kù)函數(shù)
創(chuàng)建了一個(gè)叫object的對(duì)象,使用對(duì)象的get_a方法從數(shù)據(jù)庫(kù)tdb_goods中選出cate_id=1的一條記錄,在get_a函數(shù)最后位置斷開(kāi)數(shù)據(jù)庫(kù)連接
結(jié)果如下:
插入記錄到數(shù)據(jù)庫(kù)
import MySQLdbclass Mysql(object): def __init__(self): self.connect() def connect(self): try: self.conn = MySQLdb.connect( host = '127.0.0.1', user = 'root', passwd = '********', db = 'test', port = 3306, charset = 'utf8' ) except MySQLdb.Error as e: print('Error:%s' % e) def close_conn(self): try: if self.conn: self.conn.close() except MySQLdb.Error as e: print('Error:%s' % e) def get_a(self): sql = 'select * from `tdb_goods` where `cate_id` = %s;' cursor = self.conn.cursor() cursor.execute(sql,('1',)) data = cursor.fetchone() print(data) cursor.close() self.close_conn() def add_a(self): sql = "insert into `tdb_goods`(`goods_name`,`cate_id`,`brand_id`,`goods_price`,`is_show`,`is_saleoff`) value (%s,%s,%s,%s,%s,%s);" cursor = self.conn.cursor() cursor.execute(sql,('偉哥牌notebook','8','1','66666','1','0')) cursor.close() self.close_conn() def main(): object = Mysql() object.add_a() if __name__ == '__main__': main()
注:這里,將一條記錄插入了數(shù)據(jù)庫(kù),但是當(dāng)我執(zhí)行完這條語(yǔ)句(沒(méi)報(bào)錯(cuò))
刷新數(shù)據(jù)庫(kù)并沒(méi)有新增一條記錄
劃重點(diǎn):在這里,有一個(gè)self.connmit(),這個(gè)叫提交,如果不寫(xiě)這句,就無(wú)法將所做修改保存的數(shù)據(jù)庫(kù)中
加上這個(gè)之后(加在以下兩句之間):
可以看到,數(shù)據(jù)成功寫(xiě)入數(shù)據(jù)庫(kù)了~
如果運(yùn)行代碼報(bào)錯(cuò),很可能是你的數(shù)據(jù)庫(kù)名和數(shù)據(jù)庫(kù)登錄密碼沒(méi)有修改~
文中如有錯(cuò)誤和敘述不妥之處,望指正。
Python數(shù)據(jù)庫(kù)操作技巧 互聯(lián)網(wǎng)視頻課程
在日常的程序序開(kāi)發(fā)過(guò)程中,經(jīng)常要跟關(guān)系數(shù)據(jù)庫(kù)打交道。python異步連接數(shù)據(jù)庫(kù)用aiomysql,筆者就在使用此庫(kù)過(guò)程中的一些心得和技巧記錄如下。
我們先看一下同步數(shù)據(jù)庫(kù)連接方法,PyMySQL官方給的使用方法如下:
在日常使用過(guò)程序中,如果均采用這樣的方法來(lái)操作數(shù)據(jù)庫(kù),代碼的編寫(xiě)量很大,而且容易出錯(cuò),現(xiàn)就異步程序數(shù)據(jù)庫(kù)連接解決辦法歸納如下,如果是同步程序,就可以依據(jù)異步程序相應(yīng)做修改即可,思路是一模一樣的:
創(chuàng)建連接池
我們需要?jiǎng)?chuàng)建一個(gè)全局的連接池,每個(gè)HTTP請(qǐng)求都可以從連接池中直接獲取數(shù)據(jù)庫(kù)連接。使用連接池的好處是不必頻繁地打開(kāi)和關(guān)閉數(shù)據(jù)庫(kù)連接,而是能復(fù)用就盡量復(fù)用。缺省情況下將編碼設(shè)置為utf8,自動(dòng)提交事務(wù):
import logging
import aiomysql #這是異步操作pymysql的庫(kù)
DATABASES = { 'host':'127.0.0.1',
'port':3306,
'user':'root',
'password':'',
'db':'mydb',
'charset':'utf8mb4',
# 'cursorclass':pymysql.cursors.DictCursor }
async def create_pool(loop, **kw):
"""定義mysql全局連接池"""
logging.info('create database connection pool...')
global _mysql_pool
_mysql_pool = await aiomysql.create_pool(host=DATABASES['host'], port=DATABASES['port'], user=DATABASES['user'],
password=DATABASES['password'], db=DATABASES['db'], loop=loop,
charset=kw.get('charset', 'utf8'), autocommit=kw.get('autocommit', True),
maxsize=kw.get('maxsize', 10), minsize=kw.get('minsize', 1))
return _mysql_pool
封裝增刪改查
訪問(wèn)數(shù)據(jù)庫(kù)需要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)連接、游標(biāo)對(duì)象,然后執(zhí)行SQL語(yǔ)句,最后處理異常,清理資源。這些訪問(wèn)數(shù)據(jù)庫(kù)的代碼如果分散到各個(gè)函數(shù)中,勢(shì)必?zé)o法維護(hù),也不利于代碼復(fù)用。所以,我們要首先把常用的SELECT、INSERT、UPDATE和DELETE操作用函數(shù)封裝起來(lái)。由于Web框架使用了基于asyncio的aiohttp,這是基于協(xié)程的異步模型。在協(xié)程中,不能調(diào)用普通的同步IO操作,因?yàn)樗杏脩舳际怯梢粋€(gè)線程服務(wù)的,協(xié)程的執(zhí)行速度必須非???,才能處理大量用戶的請(qǐng)求。而耗時(shí)的IO操作不能在協(xié)程中以同步的方式調(diào)用,否則,等待一個(gè)IO操作時(shí),系統(tǒng)無(wú)法響應(yīng)任何其他用戶。這就是異步編程的一個(gè)原則:一旦決定使用異步,則系統(tǒng)每一層都必須是異步,“開(kāi)弓沒(méi)有回頭箭”。幸運(yùn)的是 aiomysql 為MySQL數(shù)據(jù)庫(kù)提供了異步IO的驅(qū)動(dòng)。
1. 要執(zhí)行SELECT語(yǔ)句,我們用select函數(shù)執(zhí)行,需要傳入SQL語(yǔ)句和SQL參數(shù):
async def fetchone(sql, args=(), size=None):
"""封裝select,查詢(xún)單個(gè),返回?cái)?shù)據(jù)為字典"""
log(sql, args)
async with _mysql_pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute(sql, args)
result = await cur.fetchone()
return result
async def select(sql, args=(), size=None):
"""封裝select,查詢(xún)多個(gè),返回?cái)?shù)據(jù)為列表"""
log(sql, args)
async with _mysql_pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute(sql, args)
if size:
result = await cur.fetchmany(size)
else:
result = await cur.fetchall()
logging.info('rows returned: %s' % len(result))
return result
注意要始終堅(jiān)持使用帶參數(shù)的SQL,而不是自己拼接SQL字符串,這樣可以防止SQL注入攻擊。如果傳入size參數(shù),就通過(guò)fetchmany()獲取最多指定數(shù)量的記錄,否則,通過(guò)fetchall()獲取所有記錄。
2. 封裝Insert, Update, Delete
要執(zhí)行INSERT、UPDATE、DELETE語(yǔ)句,可以定義一個(gè)通用的execute()函數(shù),因?yàn)檫@3種SQL的執(zhí)行都需要相同的參數(shù),以及返回一個(gè)整數(shù)表示影響的行數(shù):
async def execute(sql, args=()):
"""封裝insert, delete, update"""
log(sql, args)
async with _mysql_pool.acquire() as conn:
async with conn.cursor() as cur:
try:
await cur.execute(sql, args)
except BaseException:
await conn.rollback()
return
else:
affected = cur.rowcount
return affected
execute()函數(shù)和select()函數(shù)所不同的是,cursor對(duì)象不返回結(jié)果集,而是通過(guò)rowcount返回結(jié)果數(shù)。