python-MySQL数据库基础(三)MySQL与python交互

MySQL与python交互

在这里插入图片描述
用python代码来连接数据库,执行SQL语句,来查询到数据库中的数据。
当一张表中的数据量比较多时,而我们只需要查询其中的某个字段数据,直接查询会导致效率降低,此时就需要建立分表。

python操作MySQL步骤

安装pymysql

pip install pymysql

connection对象,建立与数据库的连接,创建对象:调用connect()方法。
cursor,游标,读取一行一行的数据
在这里插入图片描述
代码实现过程如下

# 第一种导入
# from pymysql import *
# connect()
# 第二种导入
import pymysql
# 1.连接数据库,user和password 都是直接设置的
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='hww-sql',db='shopping',charset='utf8')
# 2.获取游标对象
cs = conn.cursor()

# 3. 通过游标对象执行sql语句,受影响的行数
r =cs.execute('select * from goods;')
print(r)  # 得到的是数据的条数21

# 4. 获取数据,通过游标获取数据,执行完一行,游标会在第二行
print(cs.fetchone())  # 获取的是第一条数据
print(cs.fetchone())  # 获取的是第二条数据
# 4.1 fechmany(),默认不传参数,返回一条数据
print(cs.fetchmany())
print(cs.fetchmany(2))  # 括号内的数字是获取数据的条数
# 4.2 获取全部的数据
# print(cs.fetchall())  # 获取全部的数据
# 获取全部数据后,再去获取数据就得不到数据,返回None
# print(cs.fetchone())  # None,获取所有数据后,游标在末尾不会重新获取

# 5. 关闭
# 5.1 关闭游标
cs.close()
# 5.2 关闭连接
conn.close()

# 关闭后还可以获取数据,有缓存的
print('*'*50)
print(cs.fetchone())

异常捕获

当端口号等信息出现错误的时候,为了保证程序的正常运行,就需要进行异常捕获

import pymysql
try:
    conn = pymysql.connect(host='127.0.0.1',port=3307,user='root',passwd='hww-sql',db='shopping',charset='utf8')
except Exception as e:
    print(e) # e是对象,并不是元组,代表的是Exception
    print(e.args[0])  # 取出第一个值 2003

封装DB

用类来做封装,单独分成模块,实现单独的某个功能。

from pymysql import *

'''
1.连接数据库,在实例化的时候连接数据库
2.实现程序执行完毕后,自动关闭
'''
class MyDb(object):
    # 2.初始化,自动连接数据库
    def __init__(self):
        self.my_conn()
    # 1.定义连接数据库的方法
    def my_conn(self):
        # 实例化方法
        try:
            self.conn = connect(host='127.0.0.1',port=3306,user='root',passwd='hww-sql',db='shopping',charset='utf8')
        except Exception as e:
            print(e)

    # 3. 获取单条数据
    def get_one(self):
        # 3.1 获取游标
        cs = self.conn.cursor()
        # 3.2 执行sql语句
        sql = 'select * from goods'
        # 执行sql语句
        cs.execute(sql)
        # 3.3 获取执行的结果
        res = cs.fetchone()
        # 3.4 只关闭游标
        cs.close()
        return res

    # 4. 获取全部数据
    def get_all(self):
        # 4.1 获取游标
        cs = self.conn.cursor()
        # 4.2 执行sql语句
        sql = 'select * from goods'
        # 执行sql语句
        cs.execute(sql)
        # 4.3 获取执行的结果
        res = cs.fetchall()
        # res = cs.fetchmany(5) # 传入参数值
        # 4.4 只关闭游标
        cs.close()
        return res
    # 关闭连接,需把关闭连接单独定义,否则第二次调用的时候连接就关闭了
    # def close_conn(self):
    #     self.conn.close()
    # 程序执行完毕之后,自动执行关闭的方法
    def __del__(self):
        self.conn.close()
def main():
    # 实例化对象
    db =MyDb()
    # data =db.get_one()  # 每次执行都会创建一个游标
    # print(data)
    # data = db.get_one()  # 访问的始终的第一个数据,因为每次执行都重新创建一个游标
    # print(data)
    all_data = db.get_all()
    # print(all_data)
    # 遍历取出所有数据
    for data in all_data:
        print(data)
if __name__ == '__main__':
    main()

首先导入库,用类进行封装,代码的框架为,定义类、函数main()、程序的入口。定义连接数据库的方法,用init方法在实例化的时候就自动进行连接数据库,然后是进行获取数据,获取单条数据,先获取游标,再执行sql语句,获取执行的结果,最后关闭游标和连接,把获取到的res 返回到main函数里函数的调用处。如果进行二次函数调用的话就报错,因为第一次调用后,与数据库的连接已经关闭了,为了反复获取数据,需要把关闭连接单独存放。关闭游标不用单独存放,因为方法调用的时候每次都重新定义了游标,所以每次取值都是从第一条数据开始取。定义获取多条数据的函数,跟获取单条数据的函数类似,在main函数里调用函数,获取到全部的数据,数据获取得到的是元组,可以用遍历的方法逐个取出。对代码进行优化,用del方法实现在代码执行结束的时候自动执行关闭连接。

插入数据

导入库,创建操作数据库的函数,进行数据库的连接、获取游标、插入数据、执行sql语句、关闭游标和连接。程序正常运行但是未能增加数据,此时为引擎的问题,MyIsAM 不需要提交事务就可以修改数据;Innodb 修改表的数据,需要进行提交事务(安全性更高),需要在关闭游标前用commit提交事务,此时数据表的内容就可以添加进去了。如果有多个sql语句,一个commit可以提交多个事务。添加数据语句发生错误,数据不能正常添加进去,但是会占用数据表中的id,因为服务器端会接收。
如果执行多条sql语句,只要有一条错误,就不进行添加,好比银行卡转钱,信息错误会自动返回原账户,可以用回滚来实现 conn.rollback()。用try,except来捕捉问题。

import pymysql
def coperation_db():
    try:
        # 连接数据库
        conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='hww-sql',db='mytest-01',charset='utf8')
        # 获取游标
        cs = conn.cursor()
        # 插入数据
        sql = "insert into mytable1 (name) value ('xiaoming11');"
        # 执行sql语句
        cs.execute(sql)
        # 插入数据
        sql = "insert into mytable1 (name) value ('xiaoming22');"
        # 执行sql语句
        cs.execute(sql)
        # 提交事务,一次性可以提交多个
        conn.commit()
        # 关闭游标
        cs.close()
        # 关闭连接
        conn.close()
    except  Exception as e:
        conn.rollback()
        
if __name__ == '__main__':
    coperation_db()

在这里插入图片描述

使用面向对象完成商品的查询

'''
输入1:查询所有商品
输入2:所有商品种类
输入3:查询所有品牌
输入4:退出
输入5:插入数据
'''
import pymysql
class Shopping(object):
    def __init__(self):
        self.conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='hww-sql',db='shopping',charset='utf8')
        self.cs =self.conn.cursor()
    # 用户输入的模板
    def run(self):
        while True:
            num = self.print_meun()
            if num == '1':
                self.show_all_goods()
            elif num == '2':
                self.show_all_cates()
            elif num == '3':
                self.show_all_brands()
            elif num == '4':
                break
            elif num == '5':
                self.add_cate()
            else:
                print('你输入的内容错误')
    # 写入的内容不需要参数,不需要self
    # 静态方法的装饰器
    @staticmethod
    def print_meun():
        print('-----shop-----')
        print('输入1:查询所有商品')
        print('输入2:所有商品种类')
        print('输入3:查询所有品牌')
        print('输入4:退出')
        print('输入5:插入数据')
        num = input('请输入选项:')
        return num
    # 查询所有的商品,避免代码重复写,把执行sql语句,获取所有的结果,遍历循环得到的数据单独列出来
    def show_all_goods(self):
        sql = 'select * from goods'
        self.excute_sql(sql)
    # 查询所有的商品种类
    def show_all_cates(self):
        sql = 'select * from goods_cates'
        self.excute_sql(sql)

    # 查询所有的品牌,并进行去重
    def show_all_brands(self):
        sql = 'select distinct brand_name from goods'
        self.excute_sql(sql)

    # 添加商品分类
    def add_cate(self):
        name = input('请输入商品分类名字:')
        # 要注意 value 后跟的是字符串,格式化字符串后得到数据不带引号,要在格式化字符串的时候加上引号
        # f"-- insert into goods_cates (name) value (商品信息)"
        sql = f"insert into goods_cates (name) value ('{
      
      name}')"
        self.excute_sql(sql)
        # 提交事务
        self.conn.commit()
    # 单独定义函数,执行sql语句,减少重复代码
    def excute_sql(self,sql):
        self.cs.execute(sql)
        res = self.cs.fetchall()
        for data in res:
            print(data)
    # 自动关闭连接
    def __del__(self):
        self.conn.commit()

def main():
    shop = Shopping()
    shop.run()
if __name__ == '__main__':
    main()

导入库,搭建代码的框架,创建购物类,定义main函数,建立主程序的入口。在实例化对象,初始化的时候就进行连接数据库、获取游标对象。创建输入模板,用于用户进行选择,提示用户进入模块,提示用户输入,可以用whlie True进行死循环状态,一直进行输入。判断接收用户的输入是否为1-4,进行判断并分别执行不同的代码。输入模板函数种的self与一系列print没有关系,可以单独把print的内容拿出来,利用静态方法的装饰器,定义里面没有任何参数的函数,在while True里调用此函数。定义查询所有商品的函数,创建查询,执行sql语句,获取所有的结果,遍历循环得到的数据。然后定义所有商品种类、查询所有的品牌,函数中的执行sql语句、获取所有的结果、遍历循环内容都是重复的,可以把重复的内容进行单独的封装,单独定义函数用来执行sql语句,然后在每个函数里调用此方法。根据用户输入的内容,分别调用这几个函数。

视图

视图(view)是一种虚拟存在的表,对于使用视图的用户来说基本上是透明的,视图并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的.

  1. 定义视图 create view 视图名称 as select 语句;
  2. 查看视图,查看表的时候会把视图表页列出来 show tables;
  3. 使用视图 select * from v_pro;
  4. 删除视图 drop view 视图名称

视图的作用:

  • 简单:提高了重用性,就像一个函数,避免代码的重复书写
  • 安全:提高了安全性能,可以针对不同的用户,设定不同的视图,比如公司的薪水不让别人查看,可以构建一个不带薪水的视图,供员工查看
  • 数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

有以下内容出现,不能进行视图的修改。

  • select子句中包含distinct、组函数
  • select语句中包含group by、order by子句以及相关子查询
  • from子句中包含多个表
  • 如果视图中有计算量,则不能更新
  • 如果基表中有某个具有非空约束的列未出现在视图定义中,则不能做insert操作

猜你喜欢

转载自blog.csdn.net/hwwaizs/article/details/128722541