• 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 来表示了,因为是我个人的服务器不便于公开,实际中大家改成自己的就可以了。

  • 相关阅读:
    Kibana6.8.6简单操作手册
    自学思科SD-WAN Zero Touch Provisioning(ZTP)零接触配置
    自学思科SD-WAN Zone Based Firewall(ZBF)区域防火墙
    自学思科SD-WAN Application Aware Routing(AAR)应用感知路由
    自学思科SD-WAN策略框架-本地策略(控制策略+数据策略)
    自学思科SD-WAN策略框架-集中式数据策略
    自学思科SD-WAN策略框架-集中式控制策略
    国密算法说明SM2、SM3、SM4
    Docker Desktop 通过本地命令运行.net core程序
    关于windows使用docker的总结
  • 原文地址:https://www.cnblogs.com/mryrs/p/6951008.html
Copyright © 2020-2023  润新知