第三篇 Python關於mysql的API--pymysql模塊, mysql事務

python關於mysql的API--pymysql模塊

pymysql是Python中操做MySQL的模塊,其使用方法和py2的MySQLdb幾乎相同。python

模塊安裝

pip install pymysql

在Pycharm裏執行sql會遇到「SQL dialect is not configured」,解決辦法:mysql

在File---->Setting--->Languages & Frameworks--->SQL Dialects中,選擇對應的數據庫,如MySQL,以後點擊保存便可sql

 

執行sql語句

在Python裏寫原生sql,就是把原生sql放到了一個接口裏去執行數據庫

import pymysql

# 1. 鏈接數據庫後返回可是一個鏈接對象,有這個鏈接對象,就能夠對數據庫進行操做
conn = pymysql.connect(
    host = "127.0.0.1",   # 數據庫的ip地址
    port = "3306",        # 數據庫的端口號
    user = "root",        # 登錄數據庫的用戶名
    passwd = "123456",    # 登錄數據庫的密碼
    db = "lesson54"       # 要鏈接的數據庫,必須提早建立好,不然會鏈接出錯
)

# 2.獲取遊標
# 有了遊標,具體的sql語句就能夠經過這個遊標來執行了
cursor = conn.cursor()  # 返回的結果是一個元組的形式
cursor1 = conn.cursor(cursor1 = pymysql.cursors.DictCursor) # 返回的就是字典形式的光標

# 經過execute執行sql語句
# cursor.execute("具體的sql語句,增刪改查")

# 3. 建立表
sql = "create table TEST(id int,name varchar (20))"  # 建立表的語句,複製給sql變量
cursor.execute(sql)   # 調用execute,建立表
cursor.execute()

# 4. 插入數據
ret =cursor.execute("insert into test values (1,'alex'),(2,'alvin')")
print(ret)  # 2, 返回的結果就是影響的行數

# 5. 查詢
ret2 = cursor.execute("select * from test")
print(ret2)

# 6.拿到查詢到的結果
print(cursor.fetchone())   # 從查詢到的結果裏取出一條,此時遊標已經不在第一行了,而在下一行了
print(cursor.fetchall())   # 取出全部查詢到的結果,因此此時取到的是剩下的全部數據
print(cursor.fetchmany(3))  # 指定取出3條查詢結果

# 7. 調節遊標的位置
# 上面6的步驟,遊標的位置發生了變化
# 相對調節:根據當前遊標的位置,進行向上或者向下調節幾行
cursor.scroll(1,mode="relative") # 正數:向下, 負數:向上

# 絕對調節:無論當前遊標在第幾行,直接調整到第一行,調到幾行數字就寫幾
cursor.scroll(1,mode="absolute")  



# .建立了鏈接對象,就要提交,提交以後再把鏈接關閉
conn.commit()
cursor.close()
conn.close()

若是放到了ORM裏,就會徹底有一套本身的語法去代替sql語句安全

 

事務

事務命令

事務指邏輯上的一組操做,組成這組操做的各個單元,要不所有成功,要不所有不成功。服務器

數據庫開啓事務命令 session

start transaction 開啓事務
Rollback 回滾事務,即撤銷指定的sql語句(只能回退insert delete update語句),回滾到上一次commit的位置 Commit 提交事務,提交未存儲的事務 savepoint 保留點 ,事務處理中設置的臨時佔位符 你能夠對它發佈回退(與整個事務回退不一樣) 

 轉帳實例:併發

UPDATE account set balance=balance-5000 WHERE name=」yuan」;
UPDATE account set balance=balance+5000 WHERE name=」xialv」;
-- 建立表
create table test2(id int PRIMARY KEY auto_increment,name VARCHAR(20)) engine=innodb;

-- 插入數據
INSERT INTO test2(name) VALUE ("alvin"),
                              ("yuan"),
                              ("xialv");



start transaction; -- 開啓事務
insert into test2 (name)values('silv');
select * from test2;
commit;   -- 提交事務


-- 保留點

start transaction;
insert into test2 (name)values('wu');
savepoint insert_wu; -- 給上面剛纔insert的命令起了個名字叫insert_wu,並設置一個保留點,對重要的sql,要緊挨着設置保留點
select * from test2;



delete from test2 where id=4;
savepoint delete1;
select * from test2;


delete from test2 where id=1;
savepoint delete2;
select * from test2;

rollback to delete1;  -- 回滾到某個設置的節點


select * from test2;

savepoint

python中調用數據庫啓動事務的方式less

import pymysql

#添加數據

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='yyy')

cursor = conn.cursor()


try:
    insertSQL0="INSERT INTO ACCOUNT2 (name,balance) VALUES ('oldboy',4000)"
    
    # 下面的是一組事務
    insertSQL1="UPDATE account2 set balance=balance-30 WHERE name='yuan'"
    insertSQL2="UPDATE account2 set balance=balance+30 WHERE name='xialv'"

    cursor = conn.cursor()

    cursor.execute(insertSQL0)
    conn.commit()

    cursor.execute(insertSQL1)
    raise Exception  # 模擬inserSQL2出現異常
    cursor.execute(insertSQL2)
    cursor.close()
    conn.commit()

except Exception as e:

    conn.rollback()  # 上面模擬insertSQL2出現異常了,就會執行回滾,回滾到上一次commit的地方
    conn.commit()


cursor.close()
conn.close()

事務特性

<1> 原子性(Atomicity):原子性是指事務是一個不可分割的工做單位,事務中的操做要麼都發生,要麼都不發生。數據庫設計

<2> 一致性(Consistency):事務先後數據的完整性必須保持一致。在事務執行以前數據庫是符合數據完整性約束的,不管事務是否執行成功,事務結束後的數據庫中的數據也應該是符合完整性約束的。在某一時間點,若是數據庫中的全部記錄都能保證知足當前數據庫中的全部約束,則能夠說當前的數據庫是符合數據完整性約束的。
好比刪部門表前應該刪掉關聯員工(已經創建外鍵),若是數據庫服務器發生錯誤,有一個員工沒刪掉,那麼此時員工的部門表已經刪除,那麼就不符合完整性約束了,因此這樣的數據庫也就性能太差啦!

<3>隔離性(Isolation):事務的隔離性是指多個用戶併發訪問數據庫時,一個用戶的事務不能被其它用戶的事務所幹擾,多個併發事務之間數據要相互隔離。

<4>持久性(Durability):持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即便數據庫發生故障也不該該對其有任何影響。

3、隔離性:
將數據庫設計爲串行化程的數據庫,讓一張表在同一時間內只能有一個線程來操做。若是將數據庫設計爲這樣,那數據庫的效率過低了。因此數據庫的設計這沒有直接將數據庫設計爲串行化,而是爲數據庫提供多個隔離級別選項,使數據庫的使用者能夠根據使用狀況本身定義到底須要什麼樣的隔離級別。

不考慮隔離性可能出現的問題:

髒讀

--一個事務讀取到了另外一個事務未提交的數據,這是特別危險的,要盡力防止。
        a 1000
        b 1000
        a:
            start transactionupdate set money=money+100 where name=b;
        b:
            start transaction;
            select * from account where name=b;--1100
            commit;
        a:
            rollback;
        b:  start transaction;
            select * from account where name=b;--1000

不可重複讀

--在一個事務內讀取表中的某一行數據,屢次讀取結果不一樣。(一個事務讀取到了另外一個事務已經提交
-- 的數據--增長記錄、刪除記錄、修改記錄),在某寫狀況下並非問題,在另外一些狀況下就是問題。

a:
start transaction;
select 活期帳戶 from account where name=b;--1000    活期帳戶:1000
select 按期帳戶 from account where name=b;--1000   按期帳戶:1000
select 固定資產 from account where name=b;--1000   固定資產:1000
------------------------------
b:
start transaction;
update set money=0 where name=b;
commit;
------------------------------
select 活期+按期+固定 from account where name=b; --2000 總資產: 2000

虛讀

是指在一個事務內讀取到了別的事務插入的數據,致使先後讀取不一致。
(一個事務讀取到了另外一個事務已經提交的數據---增長記錄、刪除記錄),在某寫狀況下並非問題,在另外一些狀況下就是問題。 b 1000 c 2000 d 3000 a: start transaction select sum(money) from account;---3000 3000 ------------------- d:start transaction; insert into account values(d,3000); commit; ------------------- select count(*)from account;---3 3 3000/3 = 1000 1000

四個隔離級別:
Serializable:可避免髒讀、不可重複讀、虛讀狀況的發生。(串行化)
Repeatable read:可避免髒讀、不可重複讀狀況的發生。(可重複讀)不能夠避免虛讀
Read committed:可避免髒讀狀況發生(讀已提交)
Read uncommitted:最低級別,以上狀況均沒法保證。(讀未提交)

安全性考慮:Serializable>Repeatable read>Read committed>Read uncommitted
數據庫效率:Read uncommitted>Read committed>Repeatable read>Serializable

通常狀況下,咱們會使用Repeatable read、Read committed mysql數據庫默認的數據庫隔離級別Repeatable read

mysql中設置數據庫的隔離級別語句:

set [global/session] transaction isolation level xxxx;

若是使用global則修改的是數據庫的默認隔離級別,全部新開的窗口的隔離級別繼承自這個默認隔離級別若是使用session修改,則修改的是當前客戶端的隔離級別,和數據庫默認隔離級別無關。當前的客戶端是什麼隔離級別,就能防止什麼隔離級別問題,和其餘客戶端是什麼隔離級別無關。
mysql中設置數據庫的隔離級別語句:

select @@tx_isolation;
相關文章
相關標籤/搜索