Python Every Day, 第 20 天 在工作中,不管Web開發(fā)或者爬蟲,數(shù)據(jù)分析等凡是與數(shù)據(jù)有接觸的都離不開數(shù)據(jù)庫。數(shù)據(jù)庫又分為關系型數(shù)據(jù)庫還是非關系型數(shù)據(jù)庫,關系型數(shù)據(jù)庫中最常用應該就是MySQL了。在Python中可以通過PyMySQL庫完成對其的操作。安裝PyMySQL 操作過程大概分為如下幾步 1、創(chuàng)建數(shù)據(jù)庫連接2、創(chuàng)建cursor,用于執(zhí)行sql創(chuàng)建test庫,并在該庫中創(chuàng)建fund_info(資產(chǎn)信息表)CREATE DATABASE `test` ; use test; CREATE TABLE `fund_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `account` varchar(50) NOT NULL COMMENT '賬號', `amount` decimal(10,2) DEFAULT NULL COMMENT '總金額', `consume` decimal(10,2) DEFAULT '0.00' COMMENT '消費金額', `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `modify_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1
具體操作(增刪改查)看示例代碼吧,在代碼中盡可能的都注釋了。import pymysql
# 創(chuàng)建MySQL連接 connection = pymysql.connect(host='127.0.0.1', # MySQL服務器地址 port=3306, # 服務端口號 user='root', # MySQL用戶名 password='root', # MySQL密碼 db='test', # 要操作的數(shù)據(jù)庫名稱 charset='utf8mb4') # 連接編碼 # 創(chuàng)建cursor, 用于執(zhí)行sql cursor = connection.cursor()
# 增加兩條記錄。 insert_sql = 'insert into fund_info (account, amount) values ('abc@163.com', 100.00)' insert_sql1 = 'insert into fund_info (account, amount) values ('zxc@163.com', 99.00)' # 執(zhí)行上面兩個sql, cursor.execute(insert_sql) cursor.execute(insert_sql1) # 執(zhí)行增 刪 改時 需要commit,不然不會生效 connection.commit()
# 查詢剛才插入的兩條數(shù)據(jù) cursor.execute('select * from fund_info') # fetchall 查看執(zhí)行的全部結果,返回一個tuple result_all = cursor.fetchall() ''' 輸出: result_all : ((2, 'abc@163.com', Decimal('100.00'), Decimal('0.00'), datetime.datetime(2019, 8, 7, 16, 57, 49), datetime.datetime(2019, 8, 7, 16, 57, 49)), (3, 'zxc@163.com', Decimal('99.00'), Decimal('0.00'), datetime.datetime(2019, 8, 7, 16, 57, 49), datetime.datetime(2019, 8, 7, 16, 57, 49))) ''' print('result_all :', result_all)
# 通過id查詢 cursor.execute('select amount from fund_info where account='abc@163.com'') # fetone 仍然返回元組 result_amount = cursor.fetchone() print(result_amount) # (Decimal('100.00'),)
# 更新 賬號:abc@163.com 的amount值為200.00 cursor.execute('update fund_info set amount=200.00 where account='abc@163.com'') # 執(zhí)行增 刪 改時 需要commit,不然不會生效 connection.commit() print('更新成功.')
cursor.execute('delete from fund_info where account='abc@163.com'') # 執(zhí)行增 刪 改時 需要commit,不然不會生效 connection.commit() print('刪除成功.')
# 操作完畢之后,必須要關閉連接 cursor.close() connection.close()
以上是用PyMySQL操作MySQL的基本知識。這里想再啰嗦一下事務。事務
事務: 事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功。通俗的將:我執(zhí)行多個sql如果其中一個失敗了,那要將之前修改的數(shù)據(jù)進行還原。回滾到執(zhí)行前的狀態(tài)。拿我們上面的sql來舉例,對于一個賬號 account,資金amount、消費金額consume。我們購物的時候,消費金額增加的同時,錢包里的金額就要對應的減少。 這個增加和減少就是一個事務,不可能只增加消費金額,而不減少總金額。今天只說一下PyMySQL對事務的處理(如果在MySQL終端進行事務操作,需要手動開啟 -- start transaction;)mysql> select amount from fund_info where account = 'zxc@163.com'; +--------+ | amount | +--------+ | 99.00 | +--------+ 1 row in set (0.00 sec)
import pymysql
connection = pymysql.connect(host='127.0.0.1', # MySQL服務器地址 port=3306, # 服務端口號 user='root', # MySQL用戶名 password='root', # MySQL密碼 db='test', # 要操作的數(shù)據(jù)庫名稱 charset='utf8mb4') # 連接編碼 # 創(chuàng)建cursor, 用于執(zhí)行sql cursor = connection.cursor()
# 代表消費的金額 price = 15
# 此時賬戶zxc的總金額為99 # 賬戶zxc@163.com 總金額 - price sql_1 = f'update fund_info set amount = amount - {price} where account = 'zxc@163.com'' # 賬戶zxc@163.com 消費金額 + price sql_2 = f'update fund_info set consume = consume + {price} where account = 'zxc@163.com''
try: # 查詢余額是否足夠 cursor.execute('select amount from fund_info where account = 'zxc@163.com'') result = cursor.fetchone() print(result[0]) # 如果余額不足 拋出異常. if not result or result[0] < price: raise Exception('余額不足...') cursor.execute(sql_1) print('========= 其他業(yè)務邏輯 執(zhí)行中....') cursor.execute(sql_2) except Exception as e: # 事務回滾 connection.rollback() print(e) finally: # 提交sql connection.commit() # 關閉連接 cursor.close() connection.close()
mysql> select amount from fund_info where account = 'zxc@163.com'; +--------+ | amount | +--------+ | 84.00 | +--------+ 1 row in set (0.00 sec)
在代碼中通過raise 模擬異常。演示一下事務的作用import pymysql
connection = pymysql.connect(host='127.0.0.1', # MySQL服務器地址 port=3306, # 服務端口號 user='root', # MySQL用戶名 password='root', # MySQL密碼 db='test', # 要操作的數(shù)據(jù)庫名稱 charset='utf8mb4') # 連接編碼 # 創(chuàng)建cursor, 用于執(zhí)行sql cursor = connection.cursor()
# 代表消費的金額 price = 15
# 此時賬戶zxc的總金額為99 # 賬戶zxc@163.com 總金額 - price sql_1 = f'update fund_info set amount = amount - {price} where account = 'zxc@163.com'' # 賬戶zxc@163.com 消費金額 + price sql_2 = f'update fund_info set consume = consume + {price} where account = 'zxc@163.com''
try: # 查詢余額是否足夠 cursor.execute('select amount from fund_info where account = 'zxc@163.com'') result = cursor.fetchone() print(result[0]) # 如果余額不足 拋出異常. if not result or result[0] < price: raise Exception('余額不足...') cursor.execute(sql_1) print('========= 其他業(yè)務邏輯 執(zhí)行中....') raise Exception('模擬業(yè)務邏輯異常......') cursor.execute(sql_2) except Exception as e: print('---- 開始事務回滾') # 事務回滾 connection.rollback() print(e) finally: # 提交sql connection.commit() # 關閉連接 cursor.close() connection.close() print('執(zhí)行完畢')
控制條輸出 ========= 其他業(yè)務邏輯 執(zhí)行中.... ---- 開始事務回滾 模擬業(yè)務邏輯異常...... 執(zhí)行完畢
查詢mysql mysql> select amount from fund_info where account = 'zxc@163.com'; +--------+ | amount | +--------+ | 84.00 | +--------+ 1 row in set (0.00 sec)
即使執(zhí)行了sql_1(減少總金額的sql語句),金額并沒有被改變。因為在修改consume(執(zhí)行sql_2)之前程序出現(xiàn)了異常,程序就進行了事務回滾,即:connection.rollback()。所以數(shù)據(jù)被還原到了執(zhí)行事務之前的樣子。 以上,便是今天的分享,希望大家喜歡,覺得內(nèi)容不錯的,歡迎點擊「在看」支持,謝謝各位。
|