python對mysql數據庫操作的三種不同方式


 

話不多說,本博的一個技術 python對mysql的操作的三種實現方式。

再此之前先引入三個知識點:

1 :__name__=='__main__'

  這是什么意思呢? 

  1.python文件的后綴為.py

  2..py文件既可以用來直接執行,也可以用來作為模塊被導入,

  3.在python中用import導入模塊

  __name__作為模塊的內置屬性,簡單點說,就是.py文件的調用方式,如果是以模塊調用__name__就等於該模塊的名字(后文會繼續說明),如果是直接調用__name__就等於'__main__'

2:命令行傳參

  何為命令行傳參? 顧名思義 ,是在命令行傳遞參數,和常見的傳遞參數方式不同的是,命令行傳遞參數是把參數和程序寫在同一個命令行來運行。

  給個實際的圖片看一下(我用的是linux環境,如果在windows下可用dos實現):

  

  這里python3 是執行python程序的格式,pyt3.py 和pyt2.py是 .py程序的名字,而后面的 100 101 3都是參數。

  明確了這個之后,引入一個庫,sys庫,這個庫可以支持對命令行傳遞過來的參數的一些操作(后文會繼續說明)。

3:pymysql這個庫

  注意,在python3以上版本已經不支持mysqldb這個庫了,不過兩者的方法基本相同。

  這個庫的用法主要步驟如下:

  1:建立connection

  2:獲取cursor(可以把它當做一個游標)

  3:執行sql語句

  4:事務出現異常? 

  n:con.commit

  y:con.rollback

  5:獲取執行sql后的數據

  cursor.fetch

  這里提到了事務,事務又是什么呢。簡單的說,一個事務包含的所有操作都是原子操作 即 要么都執行 要么都不執行,事務有什么用呢(后文會繼續說明)

好了,回歸正題,那么python操作mysql數據庫有哪三種方式呢? 以銀行轉賬為例,先看第一種

1:普通方式

import pymysql import sys con=pymysql.Connect(host='xxx.xxx.xx.xx',port=3306,db='pytest',user='root', passwd='xxx',charset='utf8') cursor=con.cursor() def is_ava(acctid): sel_sql='select * from account where acctid=%s'%acctid cursor.execute(sel_sql) rs=cursor.fetchone() try: len(rs) except: return False return True def mon_ava(acctid,mon): selm_sql='select *from account where acctid=%s and money>=%s'%(acctid,mon) cursor.execute(selm_sql) rs=cursor.fetchone() try: len(rs) except: return False return True sr_id=sys.argv[1] tr_id=sys.argv[2] dt_money=sys.argv[3] if is_ava(sr_id) and is_ava(tr_id): if mon_ava(sr_id,dt_money): rm_sql=' update account set money=money-%s where acctid=%s'%(dt_money,sr_id) add_sql=' update account set money=money+%s where acctid=%s'%(dt_money,tr_id) try: cursor.execute(rm_sql) cursor.execute(add_sql) con.commit() except: con.rollback() finally: cursor.close() con.close()

這里純粹是面向過程的編程思想,注意代碼最后的try ,except 這里就是一個完整的事務流程,當執行remove 和add出現了異常 就進行rollback()rollback的作用就是回滾到sql語句執行前的狀態。

為什么要這樣呢? 試想這種情況:A給B的銀行卡轉賬100塊錢,即A-100 B+100.而B在此之前把此銀行卡注銷掉了, 如果不進行事務操作 就會出現:A白白丟失100塊錢的情況

而我們期望的情況是這樣:A-100 B+100 ,如果轉賬過程中出現了異常,A、B的金額都保持不變。使用事務這種原子性操作就可以確保操作的安全。

 

2:下面看第二種方法 面向對象方式

# -*- coding: utf-8 -*-

import pymysql
import sys
class TransforMoney(object):
    def __init__(self,con):
        self.con=con
        self.cursor=self.con.cursor()
    def is_ava(self,acctid):
        sel_sql='select * from account where acctid=%s'%acctid
        self.cursor.execute(sel_sql)
        rs=self.cursor.fetchone()
        try:
            len(rs)
        except:
            raise Exception
    def mon_ava(self,acctid,mon):
        selm_sql='select *from account where acctid=%s and money>=%s'%(acctid,mon)
        self.cursor.execute(selm_sql)
        rs=self.cursor.fetchone()
        try:
            len(rs)
        except:
            raise Exception
    def rd_mon(self,acctid,mon):
        rm_sql=' update account set money=money-%s where acctid=%s'%(mon,acctid)
        self.cursor.execute(rm_sql)
        if self.cursor.rowcount != 1:
            raise Exception
    def add_mon(self,acctid,mon):
        add_sql=' update account set money=money+%s where acctid=%s'%(mon,acctid)
        self.cursor.execute(add_sql)
        if self.cursor.rowcount != 1:
            raise Exception
    def transfor(self,srid,trid,mon):
        try:
            self.is_ava(srid)
            self.is_ava(trid)
            self.mon_ava(srid,mon)
            self.rd_mon(srid,mon)
            self.add_mon(trid,mon)
            self.con.commit()
        except:
            self.con.rollback()
        finally:
            self.cursor.close()
            self.con.close()
            
if __name__=='__main__':
    sr_id=sys.argv[1]
    tr_id=sys.argv[2]
    dt_money=sys.argv[3]
    con=pymysql.Connect(host='xxx.xxx.xx.xx',port=3306,db='pytest',user='root',
                    passwd='xxxxx',charset='utf8')
    tr_obj=TransforMoney(con)
    tr_obj.transfor(sr_id,tr_id,dt_money)

把所有方法都封裝到一個類里,transfor方法里同樣是事務操作,前面也說道過 __name__這個內置屬性,這個程序如果直接運行的話 __name__就等於__main,那么此時if __name__=='__main__' 就成立,即這句話相當於該程序的入口。

3:下面看第三種方式   模塊化 

# -*- coding: utf-8 -*-
"""
Created on Tue Jun  6 11:45:42 2017

@author: A
"""
import sys
import pymysql
import temp2
sr_id=sys.argv[1]
tr_id=sys.argv[2]
dt_money=sys.argv[3]
con=pymysql.Connect(host='xxx.xxx.xx.xx',port=3306,db='pytest',user='root',
                    passwd='xxxxx',charset='utf8')
tr_obj=temp2.TransforMoney(con)
tr_obj.transfor(sr_id,tr_id,dt_money)

是不是很短,沒錯,把上述第二種方式的程序保存為temp2.py ,在該程序里直接import temp2 即可調用temp2.py的類的方法,注意此時temp2.py里的__name__ 就不等於__main__了 而是等於 temp.

對了,以上的連接 host 和 passwd 我都用xxx 來表示了,因為是我個人的服務器不便於公開,實際中大家改成自己的就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM