• python之数据库操作详解


    一般来说,我们对数据库里的操作需要先连接,创建游标对象,然后通过游标对象执行SQL语句去对SQL的数据进行操作,本篇文章旨在记录与科普。

    1.cursor相关

    元组是不可变的数据类型,只能查询,不能修改,删除,新增。元组是根据索引进行取值,在实际开发的过程中一般不使用默认的元组的形式,因为索引的值取决于数据库字段的顺序,在实际的开发过程中字段的顺序是易变(比如增加了一个字段)索引就会发生改变。
    更多采用列表+字典的形式

    con = pymysql.connect(host="127.0.0.1", port=3306,
                          user="root", password='123456',
                          database="test", charset='utf8'
                          )
    
    #创建游标对象
    cur = con.cursor()
    
    #通过游标执行SQL语句
    cur.execute("SELECT * from zt_config")
    
    print(cur.fetchall())
    
    #配置游标对象以列表嵌套字典的形式返回数据
    cur = con.cursor(cursor=DictCursor)
    
    #通过游标执行SQL语句
    cur.execute("SELECT * from zt_config")
    
    #fetchall也就是一次性获取所有数据
    print(cur.fetchall())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    2.切换数据库操作
    con = pymysql.connect(host="127.0.0.1", port=3306,
                          user="root", password='123456',
                          database="test", charset='utf8'
                          )
    
    #配置游标对象以列表嵌套字典的形式返回数据
    cur = con.cursor(cursor=DictCursor)
    
    #通过游标执行SQL语句
    cur.execute("SELECT * from wyl_admin")
    
    #fetchall也就是一次性获取所有数据
    print(cur.fetchall())
    
    #切换数据的操作,使用连接对象里面的select_db进行操作
    con.select_db("stu")
    
    #通过游标执行SQL语句
    cur.execute("SELECT * from stu")
    #fetchall也就是一次性获取所有数据
    print(cur.fetchall())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    3.连接方式

    在这里,首先要想到open与with这两个命令的不同:

    • 使用with不需要手动的关闭连接
    • 使用with也是pymysql官方推荐的方式
    with pymysql.connect(host="127.0.0.1", port=3306,
                          user="root", password='123456',
                          database="test
                          
                         ", charset='utf8'
                          ) as db:
        with db.cursor(DictCursor) as cur:
            cur.execute("SELECT * from zt_config")
            print(cur.fetchall())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    4.结果集处理
    with pymysql.connect(host="127.0.0.1", port=3306,
                          user="root", password='123456',
                          database="zentao", charset='utf8'
                          ) as db:
        with db.cursor(DictCursor) as cur:
            # cur.execute("SELECT * from zt_config")
    
            cur.execute('UPDATE  zt_config set money = money-100 where `name` = "king";')
    
    #fetchone获取一条数据
    #但是每次获取完之后再次执行会继续往后面获取
    #print(cur.fetchone())
    #print(cur.fetchone())
    #print(cur.fetchone())
    
    #一次性获取所有的数据
    #print(cur.fetchall())
    
    #fetchmany在什么都不传的情况下,和fetchone是一样的
    #可以传值,值就是获取的条数
    #print(cur.fetchmany(4))
    #print(cur.fetchmany())
    #print(cur.fetchmany())0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    5.事务操作相关

    在数据库里面什么叫做事务?事务就是一段连续的不可分割的sql语句,要么全部成功,要么全部失败。在实际的开发过程中:事务必不可少。

    # 把king的钱借给jack100块
    BEGIN;      
    #表示事务开启,接下来的所有的sql语句都作为一个事务
    
    #执行sql语句之后并不会直接修改数据库,而是把修改的操作存储在内存里面
    UPDATE  zt_config set money = money-100 where `name` = "king";
    #操作
    UPDATE  zt_config set money = money+100 where `name` = "jack";
    
    #判断事务里面的sql执行没有问题才会继续提交,执行完commit之后数据库的数据才会发生改变
    COMMIT;
    
    #执行完rollback之后表示整个事务失败,所有的操作全部还原
    ROLLBACK;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    事务的四个特性:原子性,一致性,隔离性,持久性!

    1. 原子性(Atomicity)

            事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
      
      • 1
    2. 一致性(Consistency)

           事务前后数据的完整性必须保持一致。
      
      • 1
    3. 隔离性(Isolation)

          了解:
      
      • 1
    •     数据隔离的级别
      
      • 1
    •     数据每个隔离级别在不同的数据库产品里面的默认值
      
      • 1
    •     每个隔离级别所对应解决的问题(脏读,幻读,重复读...)
      
      • 1
    •     工作中应该怎么去选择隔离级别
      
          多个用户并发访问数据库时,一个用户的事务不能被其它用户的事物所干扰,多个并发事务之间的数据要相互隔离。
      
      • 1
      • 2
      • 3
    1. 持久性(Durability)

          一个事务一旦被提交,它对数据库中的数据改变就是永久性的。
      
      • 1

    例子:

    # 在pymysql里面的事务操作  面向过程
    with pymysql.connect(host="127.0.0.1", port=3306,
                          user="root", password='123456',
                          database="zentao", charset='utf8'
                          ) as db:
        with db.cursor(DictCursor) as cur:
            db.begin()      # 连接对象.begin()  表示开启事务
            try:
                cur.execute('UPDATE  zt_config set money = money-100 where `name` = "king";')
                cur.execute('UPDATE  zt_config set money = money+100 where `name` = "jack";')
            except Exception as e:
                db.rollback()  # 回滚数据
                print(e)
            else:
                db.commit()  # 提交数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    6.打包拆包相关(*args,**kwargs)
    –打包
    a.*args

    args是一个特殊的参数,它允许你在函数调用时传递任意数量的位置参数。这些位置参数将会以元组的形式传递给函数。
    在使用
    args时,你可以传递任何类型的参数,包括数字、字符串、列表、元组、甚至是自定义的对象等。

    #计算四个数之和
    def sum_test(a,b,c,d):
        return a + b + c + d
    
    print(sum_test(1, 2, 3, 4))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题来了,我也不知道要传入几个数。在不确定传入参数的情况,*args表示可以传入任意个数的参数,会把传入的参数 打包成一个元组,也叫做“不定长参数”。

    def sum_test2(*args):
        print(args)
        return sum(args)
    
    print(sum_test2(1, 2, 3,4,5))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    b.**kwargs

    在不定长参数时,可以使用**kwargs。**kwagrs会把传入的参数打包成一个字典,但是传参方式必须是 “关键字传参”。args是一个特殊的参数,它允许你在函数调用时传递任意数量的位置参数。这些位置参数将会以元组的形式传递给函数。
    在使用
    args时,你可以传递任何类型的参数,包括数字、字符串、列表、元组、甚至是自定义的对象等。

    #**kwargs:不定长参数
    def show_self(name,age):
        print(f'我的名字叫{name},我的年龄是{age}')
    
    show_self("jack",20)
    
    #不知道有几个参数
    #**kwagrs会把传入的参数打包成一个字典,但是传参方式必须是 “关键字传参”
    def show_self2(**kwargs):
        print(kwargs)
        print(f'我的名字叫{kwargs["name"]},我的年龄是{kwargs["age"]}')
    
    show_self2(name="jack",age=20,like="长条")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    c.结合使用
    def show(*args,**kwargs):
        print(args)
        print(kwargs)
    
    show(1,2,3,4,name="jack",a="b",ak="48")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    –拆包

    把在调用函数的时候传入的内容拆包,把元组/列表拆成一个个元素,把字典拆成关键字传参

    def sum_test(a,b,c,d):
        return a + b + c + d
    
    #注意:参数的数量不能错
    
    tu = [1, 2, 3, 4,]
    print(sum_test(*tu))
    
    
    def show_self(name,age):
        print(f'我的名字叫{name},我的年龄是{age}')
    
    
    #在拆包字典的时候需要注意,字典的键必须和形式参数的名字一样
    dict1 = {"name":"jack","age":20}
    show_self(**dict1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    我的第一个Spring MVC应用的过程与解释
    拍照小白入坑
    ORA-01005 vs ORA-28040
    Ethereum Classic的难度计算|猿创征文
    ROS1云课→29如何借助ROS实现走迷宫机器人
    js实现查找两个相同字符串之间的最长子字符串长度
    026-第三代软件开发-C++&QML交互
    [附源码]Python计算机毕业设计电影网站系统设计
    Go Context
    如何做好分布式任务调度——Scheduler 的一些探索
  • 原文地址:https://blog.csdn.net/xiaoyu070321/article/details/133755628