安裝
安裝mysql資料庫的難度和oracle資料庫簡直沒得比,安裝步驟如下:
安裝MariaDB
yum install mariadb mariadb-server # 安裝,centos7默認的mysql就是mariadb
systemctl start mariadb # 啟動mariadb
systemctl enable mariadb # 開機自啟動
mysql_secure_installation # 設定root密碼
mysql -uroot -p # 登錄
安裝pymysql
pip install pymysql
基本操作
資料庫基本操作主要是:
- 創建連接
- 獲取游標
- 執行sql
- 提交事務:針對非查詢性SQL
代碼
import pymysql
# connect函式打開資料庫連接
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
# cursor方法創建游標物件cur
cur = conn.cursor()
# execute方法執行SQL陳述句
cur.execute("SELECT VERSION()")
# fetchone方法獲取單條資料
data = https://www.cnblogs.com/CHLL55/p/cur.fetchone()
print ('Database version : {}'.format(data))
# 關閉游標
cur.close()
# 關閉資料庫連接
conn.close()
DDL
DDL:資料定義語言,包括創建表,創建索引等等
import pymysql
# connect函式打開資料庫連接
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
# cursor方法創建游標物件cur
cur = conn.cursor()
# 創建表
sql = '''create table user (
name char(20) not null,
age int,
sex char(1))'''
cur.execute(sql)
# 關閉游標
cur.close()
# 關閉資料庫連接
conn.close()
DML
DML:資料操作語言,包含增刪改三項操作,
insert
import pymysql
# connect函式打開資料庫連接
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
# cursor方法創建游標物件cur
cur = conn.cursor()
# 創建表
sql = '''insert into user(name, age, sex) values('suncle', 18, 'm')'''
try:
# 執行sql陳述句
cur.execute(sql)
# 提交到資料庫執行
conn.commit()
except:
# 如果發生錯誤則回滾
conn.rollback()
# 關閉游標
cur.close()
# 關閉資料庫連接
conn.close()
update
import pymysql
# connect函式打開資料庫連接
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
# cursor方法創建游標物件cur
cur = conn.cursor()
# 創建表
sql = '''update user t set t.age = 20 where t.name='suncle' '''
try:
# 執行sql陳述句
cur.execute(sql)
# 提交到資料庫執行
conn.commit()
except:
# 如果發生錯誤則回滾
conn.rollback()
# 關閉游標
cur.close()
# 關閉資料庫連接
conn.close()
delete
import pymysql
# connect函式打開資料庫連接
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
# cursor方法創建游標物件cur
cur = conn.cursor()
# 創建表
sql = '''delete from user where age=20 '''
try:
# 執行sql陳述句
cur.execute(sql)
# 提交到資料庫執行
conn.commit()
except:
# 如果發生錯誤則回滾
conn.rollback()
# 關閉游標
cur.close()
# 關閉資料庫連接
conn.close()
QUERY
基礎查詢
主要有三個函式
- cursor.fetchall 回傳行的元組
- cursor.fetchmany 回傳行的元組, 可以指定回傳前N行 相當于對fetchall切片fetchall[:N]
- cursor.fetchone 回傳首行, 相當于fetchall[0]
查詢陳述句如下:
cur.execute('''select * from user t where t.age<=19;''')
三種方法得到的結果分別為:
cur.fetchall() # (('suncle', 18, 'm'), ('suncle1', 19, 'm'))
cur.fetchmany(1) # (('suncle', 18, 'm'),)
cur.fetchone() # ('suncle', 18, 'm')
可見:每行資料也是一個元組, 元組的內容由sql決定
如果要讓回傳的資料帶上列名,也就是要回傳字典,那么就需要用到cursors.DictCursor,
DictCursor
創建cursor時創建DictCursor型別的就可以fetch回來字典形式的結果了
代碼
import pymysql
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
# 創建cursor時指定cursor引數cursor=pymysql.cursors.DictCursor表示cursor型別
cur = conn.cursor(cursor=pymysql.cursors.DictCursor)
cur.execute('''select * from user t where t.age<=20;''')
cur.fetchall()
fetchall回傳結果為:
[{'age': 18, 'name': 'suncle', 'sex': 'm'},
{'age': 19, 'name': 'suncle1', 'sex': 'm'},
{'age': 20, 'name': 'suncle2', 'sex': 'm'}]
回傳每一行記錄都是一個字典,整體結果是由字典組成的串列,而默認的cursor是由元組組成的元組,
引數化查詢
基礎的SQL注入
import pymysql
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
cur = conn.cursor()
def get_user(age=18):
sql = '''select * from user t where t.age<={};'''.format(age)
cur.execute(sql)
return cur.fetchall()
get_user() # 回傳(('suncle', 18, 'm'),)
get_user('18 or 1=1') # 回傳(('suncle', 18, 'm'), ('suncle1', 19, 'm'))
當傳入引數的age中帶sql條件的時候,就會發生sql注入,使得結果可能并不滿足要求,
為了解決sql注入,我們可以使用引數化查詢,
使用引數化查詢
以上代碼做以下修改之后就可以避免sql注入
import pymysql
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
cur = conn.cursor()
def get_user(age=18):
# 不管資料庫定義的是什么型別,統一使用%s
sql = '''select * from user t where t.age<=%s;'''.format(age)
cur.execute(sql, (age, )) # 引數化查詢
return cur.fetchall()
引數化查詢最大的優勢在于避免了SQL注入,同時引數化之后避免了sql多次硬決議,能提高查詢效率,所以,總是應該使用引數化查詢,
背景關系管理
資料庫連接和游標都支持背景關系管理,
游標
查看cur實體對應Cursor類的方法
cur = conn.cursor()
help(cur)
對應的with陳述句使用如下
with cur:
cur.execute('''select * from user''')
cur.execute('''select * from user''') # 拋出錯誤:ProgrammingError: Cursor closed
with陳述句塊結束之后cur就已經關閉了,
連接
通過help命令查看Connection類的__enter__和__exit__兩種方法的實作
conn = pymysql.connect(host='192.168.110.13', user='root', password='123456', database='student')
help(conn) # conn是Connection類
查看結果如下:
| __enter__(self)
| Context manager that returns a Cursor
|
| __exit__(self, exc, value, traceback)
| On successful exit, commit. On exception, rollback
__enter__方法會回傳一個游標__exit__方法:如果成功推出就會自動提交commit,如果發生例外就會回滾rollback
對應的with陳述句使用如下
with conn as cur:
cur.execute('''update user t set t.age = 20 where t.name='suncle' ''')
cur.execute('''select * from user''') # 退出with塊之后游標仍然沒有關閉
雖然游標沒有關閉, 但是資料庫操作已經提交,
游標和連接共同背景關系管理
with conn as cur:
with cur:
cur.execute('''update user t set t.age = 20 where t.name='suncle' ''')
退出整個背景關系管理塊之后,游標會關閉,并且會自動提交,
資料庫連接池
一般來說,應用程式訪問資料庫的程序是:
- 裝載資料庫驅動程式
- 建立資料庫連接
- 訪問資料庫,執行sql陳述句
- 斷開資料庫連接
相對于性能正常的SQL的執行效率來說,建立連接是一個費時的活動,而且系統還要為每一個連接分配記憶體資源,在現在web請求的大并發量情況下,必然會導致頻繁的資料庫操作,而頻繁的進行資料庫連接操作勢必占用很多的系統資源,使得系統的回應速度下降,嚴重的甚至會造成服務器的崩潰,
引入資料庫連接池技術之后,應用程式訪問資料庫的程序是:
- 請求資料庫操作時,從連接池中取出創建好的資料庫連接
- 執行sql陳述句
- 不斷開資料庫連接,而是放回連接池中,等待下次使用
連接池還有個優點就是能控制資料庫的壓力,當大量用戶同時涌入時,連接池只會使用池限制資料庫連接數目,而不會不停的向資料庫請求連接,最后導致服務器崩潰,
Python實作資料庫連接池
- 使用佇列Queue保存資料庫連接
代碼如下
from queue import Queue
import pymysql
class ConnectionPool(): # args和kwargs用來接收資料庫url資訊
def __init__(self, size, *args, **kwargs):
self.args = args
self.kwargs = kwargs
self.size = size
self.pool = Queue(maxsize=self.size)
for _ in range(self.size):
self.pool.put(self._connect())
def _connect(self):
return pymysql.connect(*self.args, **self.kwargs)
@staticmethod
def _close(conn):
conn.close()
def get_connection(self):
return self.pool.get()
def return_connection(self, conn):
return self.pool.put(conn)
def close_pool(self):
while not self.is_empty():
self._close(self.pool.get())
def is_empty(self):
return self.pool.empty()
def is_full(self):
return self.pool.full()
def current_connection_count(self):
return self.pool.qsize()
pool = ConnectionPool(20, host='192.168.110.13', user='root', password='123456', database='student')
conn = pool.get_connection() # 獲取資料庫連接
print(conn) # <pymysql.connections.Connection at 0x7f6290300940>
print(pool.current_connection_count()) # 19
cur = conn.cursor()
cur.execute("SELECT VERSION()")
data = https://www.cnblogs.com/CHLL55/p/cur.fetchone()
print ('Database version : {}'.format(data[0]))
cur.close()
pool.return_connection(conn) # 關閉游標之后需要回收資料庫連接
print(pool.current_connection_count()) # 20
記得幫我點贊哦!
精心整理了計算機各個方向的從入門、進階、實戰的視頻課程和電子書,按照目錄合理分類,總能找到你需要的學習資料,還在等什么?快去關注下載吧!!!

念念不忘,必有回響,小伙伴們幫我點個贊吧,非常感謝,
我是職場亮哥,YY高級軟體工程師、四年作業經驗,拒絕咸魚爭當龍頭的斜杠程式員,
聽我說,進步多,程式人生一把梭
如果有幸能幫到你,請幫我點個【贊】,給個關注,如果能順帶評論給個鼓勵,將不勝感激,
職場亮哥文章串列:更多文章

本人所有文章、回答都與著作權保護平臺有合作,著作權歸職場亮哥所有,未經授權,轉載必究!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/162322.html
標籤:Python
下一篇:1. Spring Boot入門
