日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

[每日一題]20、Python操作MySQL

 Four兄 2019-08-25

第一時(shí)間收到精彩推送!

Python Every Day, 第 20 天


    
在工作中,不管Web開(kāi)發(fā)或者爬蟲(chóng),數(shù)據(jù)分析等凡是與數(shù)據(jù)有接觸的都離不開(kāi)數(shù)據(jù)庫(kù)。數(shù)據(jù)庫(kù)又分為關(guān)系型數(shù)據(jù)庫(kù)還是非關(guān)系型數(shù)據(jù)庫(kù),關(guān)系型數(shù)據(jù)庫(kù)中最常用應(yīng)該就是MySQL了。
在Python中可以通過(guò)PyMySQL庫(kù)完成對(duì)其的操作。

安裝PyMySQL

pip3 install pymysql

操作過(guò)程大概分為如下幾步

0、在MySQL中創(chuàng)建庫(kù)和表
1、創(chuàng)建數(shù)據(jù)庫(kù)連接
2、創(chuàng)建cursor,用于執(zhí)行sql
3、編寫(xiě)并執(zhí)行SQL
4、獲取數(shù)據(jù)
5、關(guān)閉連接
通過(guò)下面一個(gè)簡(jiǎn)單的例子給大家演示一下

創(chuàng)建test庫(kù),并在該庫(kù)中創(chuàng)建fund_info(資產(chǎn)信息表)
CREATE DATABASE `test` ;
use test;
CREATE TABLE `fund_info` (
  `id` int(11NOT NULL AUTO_INCREMENT,
  `account` varchar(50NOT NULL COMMENT '賬號(hào)',
  `amount` decimal(10,2DEFAULT NULL COMMENT '總金額',
  `consume` decimal(10,2DEFAULT '0.00' COMMENT '消費(fèi)金額',
  `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服務(wù)器地址
                             port=3306,         # 服務(wù)端口號(hào)
                             user='root',       # MySQL用戶名
                             password='root',   # MySQL密碼
                             db='test',         # 要操作的數(shù)據(jù)庫(kù)名稱(chēng)
                             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í)行上面兩個(gè)sql,
cursor.execute(insert_sql)
cursor.execute(insert_sql1)
# 執(zhí)行增 刪 改時(shí) 需要commit,不然不會(huì)生效
connection.commit()

# 查詢(xún)剛才插入的兩條數(shù)據(jù)
cursor.execute('select * from fund_info')
# fetchall 查看執(zhí)行的全部結(jié)果,返回一個(gè)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)

# 通過(guò)id查詢(xún)
cursor.execute('select amount from fund_info where account='abc@163.com'')
# fetone 仍然返回元組
result_amount = cursor.fetchone()
print(result_amount) # (Decimal('100.00'),)


# 更新 賬號(hào):abc@163.com 的amount值為200.00
cursor.execute('update fund_info set amount=200.00 where account='abc@163.com'')
# 執(zhí)行增 刪 改時(shí) 需要commit,不然不會(huì)生效
connection.commit()
print('更新成功.')

cursor.execute('delete from fund_info where account='abc@163.com'')
# 執(zhí)行增 刪 改時(shí) 需要commit,不然不會(huì)生效
connection.commit()
print('刪除成功.')

# 操作完畢之后,必須要關(guān)閉連接
cursor.close()
connection.close()
以上是用PyMySQL操作MySQL的基本知識(shí)。這里想再啰嗦一下事務(wù)。

事務(wù)

事務(wù): 事務(wù)指邏輯上的一組操作,組成這組操作的各個(gè)單元,要不全部成功,要不全部不成功。
通俗的將:我執(zhí)行多個(gè)sql如果其中一個(gè)失敗了,那要將之前修改的數(shù)據(jù)進(jìn)行還原。回滾到執(zhí)行前的狀態(tài)。
拿我們上面的sql來(lái)舉例,對(duì)于一個(gè)賬號(hào) account,資金amount、消費(fèi)金額consume。我們購(gòu)物的時(shí)候,消費(fèi)金額增加的同時(shí),錢(qián)包里的金額就要對(duì)應(yīng)的減少。  這個(gè)增加和減少就是一個(gè)事務(wù),不可能只增加消費(fèi)金額,而不減少總金額。
今天只說(shuō)一下PyMySQL對(duì)事務(wù)的處理(如果在MySQL終端進(jìn)行事務(wù)操作,需要手動(dòng)開(kāi)啟 -- start transaction;)

直接看下面的例子

當(dāng)前金額:
mysql> select amount from fund_info where account = 'zxc@163.com';
+--------+
| amount |
+--------+
|  99.00 |
+--------+
1 row in set (0.00 sec)
執(zhí)行消費(fèi)代碼
import pymysql

connection = pymysql.connect(host='127.0.0.1',  # MySQL服務(wù)器地址
                             port=3306,         # 服務(wù)端口號(hào)
                             user='root',       # MySQL用戶名
                             password='root',   # MySQL密碼
                             db='test',         # 要操作的數(shù)據(jù)庫(kù)名稱(chēng)
                             charset='utf8mb4'# 連接編碼
# 創(chuàng)建cursor, 用于執(zhí)行sql
cursor = connection.cursor()

# 代表消費(fèi)的金額
price = 
15

# 此時(shí)賬戶zxc的總金額為99
# 賬戶zxc@163.com 總金額 - price
sql_1 = 
f'update fund_info set amount = amount - {price} where account = 'zxc@163.com''
# 賬戶zxc@163.com 消費(fèi)金額 + price
sql_2 = 
f'update fund_info set consume = consume + {price} where account = 'zxc@163.com''

try:
    
# 查詢(xún)余額是否足夠
    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è)務(wù)邏輯  執(zhí)行中....')
    cursor.execute(sql_2)
except Exception as e:
    
# 事務(wù)回滾
    connection.rollback()
    print(e)
finally:
    
# 提交sql
    connection.commit()
    
# 關(guān)閉連接
    cursor.close()
    connection.close()
執(zhí)行完畢,查看剩余金額:
mysql> select amount from fund_info where account = 'zxc@163.com';
+--------+
| amount |
+--------+
|  84.00 |
+--------+
1 row in set (0.00 sec)
在代碼中通過(guò)raise 模擬異常。演示一下事務(wù)的作用
import pymysql

connection = pymysql.connect(host='127.0.0.1',  # MySQL服務(wù)器地址
                             port=3306,         # 服務(wù)端口號(hào)
                             user='root',       # MySQL用戶名
                             password='root',   # MySQL密碼
                             db='test',         # 要操作的數(shù)據(jù)庫(kù)名稱(chēng)
                             charset='utf8mb4'# 連接編碼
# 創(chuàng)建cursor, 用于執(zhí)行sql
cursor = connection.cursor()

# 代表消費(fèi)的金額
price = 15

# 此時(shí)賬戶zxc的總金額為99
# 賬戶zxc@163.com 總金額 - price
sql_1 = f'update fund_info set amount = amount - {price} where account = 'zxc@163.com''
# 賬戶zxc@163.com 消費(fèi)金額 + price
sql_2 = f'update fund_info set consume = consume + {price} where account = 'zxc@163.com''

try:
    # 查詢(xún)余額是否足夠
    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è)務(wù)邏輯  執(zhí)行中....')
    raise Exception('模擬業(yè)務(wù)邏輯異常......')
    cursor.execute(sql_2)
except Exception as e:
    print('---- 開(kāi)始事務(wù)回滾')
    # 事務(wù)回滾
    connection.rollback()
    print(e)
finally:
    # 提交sql
    connection.commit()
    # 關(guān)閉連接
    cursor.close()
    connection.close()
    print('執(zhí)行完畢')

控制條輸出

========= 其他業(yè)務(wù)邏輯  執(zhí)行中....
---- 開(kāi)始事務(wù)回滾
模擬業(yè)務(wù)邏輯異常......
執(zhí)行完畢

查詢(xún)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語(yǔ)句),金額并沒(méi)有被改變。因?yàn)樵谛薷腸onsume(執(zhí)行sql_2)之前程序出現(xiàn)了異常,程序就進(jìn)行了事務(wù)回滾,即:connection.rollback()。所以數(shù)據(jù)被還原到了執(zhí)行事務(wù)之前的樣子。



以上,便是今天的分享,希望大家喜歡,覺(jué)得內(nèi)容不錯(cuò)的,歡迎點(diǎn)擊「在看」支持,謝謝各位。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多