Python MySQL数据库4:MySQL与Python交互(下)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Python MySQL数据库4:MySQL与Python交互(下)
  • 如何防止无效信息的插入,就是可以在插入前判断类型或者品牌名称是否存在呢? 可以使用之前讲过的外键来解决
  • 外键约束:对数据的有效性进行验证
  • 关键字: foreign key,只有 innodb数据库引擎 支持外键约束
  • 对于已经存在的数据表 如何更新外键约束
  • 让 cate_id 成为外键
    把 goods商品里面的最后一条数据删掉,不然后面后面外键的设置会失败


delete from goods where id=22;
  • 设置 cate_id 成为外键


alter table goods add foreign key (cate_id) references good_cates(id);
  • 这个时候我们如果在插入往 goods里面插入一条包含 cate_id = 12 的就会报错了,因为 12 在 good_cates 表里找不到


insert into goods (name,cate_id,price) values('LaserJet Pro P1606dn 黑白激光打印机', 12, '华硕','1849');
  • 报错信息:ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (jing_dong.goods, CONSTRAINT goods_ibfk_1 FOREIGN KEY (cate_id) REFERENCES good_cates (id))
    mysql>


  • 1.7、如何在创建数据表的时候就设置 外键约束 呢?,注意: goods 中的 cate_id 的类型一定要和 goods_cates 表中的 id 类型一致
  • 创表,设置外键


create table goods(
    id int primary key auto_increment not null,
    name varchar(40) default '',
    price decimal(5,2),
    cate_id int unsigned,
    brand_id int unsigned,
    is_show bit default 1,
    is_saleoff bit default 0,
    foreign key(cate_id) references goods_cates(id),
    foreign key(brand_id) references goods_brands(id)
);
  • 如何取消外键约束
    需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称


show create table goods;
  • 获取名称之后就可以根据名称来删除外键约束


alter table goods drop foreign key 外键名称;


image.png

提示: 在实际开发中,很少会使用到外键约束,会极大的降低表更新的效率


  • 1.8、上面我们已经完成了 表 good_cates 的操作,下面我们来快速的创建一下  good_brands
  • (1)、通过create...select来创建数据表并且同时写入记录,一步到位
    在创建数据表的时候一起插入数据


create table good_brands (
   id int unsigned primary key auto_increment,
   name varchar(40) not null) select brand_name as name from goods group by brand_name;


image.png

注意:需要对brand_name 用as起别名,否则name字段就没有值


  • (2)、同步数据
    通过goods_brands数据表来更新goods数据表


update goods as g inner join good_brands as b on g.brand_name=b.name set g.brand_name=b.id;
  • (3)、修改表结构
  • 查看 goods 的数据表结构,会发现 cate_name 和 brand_name对应的类型为 varchar 但是存储的都是数字


desc goods;
  • 通过alter table语句修改表结构(下面是可以同事修改另两个字段的,cate_name我们已经修改过)
    alter table goods change cate_name cate_id int unsigned not null,change brand_name brand_id int unsigned not null;


alter table goods change brand_name brand_id int unsigned not null;


image.png

  • (4)、brand_id 设置为 goods表的 外键


alter table goods add foreign key (brand_id) references good_brands(id);


  • (5)、取消外键约束
    需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称

image.png

show create table goods;
  • 获取名称之后就可以根据名称来删除外键约束


alter table goods drop foreign key 外键名称;


二、python安装pymysql 与 Python 操作



  • 2.1、在终端安装pymysqlpip3 install pymysql
  • 2.2、Python 中操作 MySQL 步骤


image.png

  • (1)、引入模块:在py文件中引入pymysql模块


from pymysql import *
  • (2)、Connection 对象
  • 用于建立与数据库的连接
  • 创建对象:调用connect()方法


conn=connect(参数列表)
例如:
conn = connect(host='域名或者IP',port=3306,database='数据库名',user='用户名',password='密码',charset='utf8')


  • 参数host:连接的mysql主机,如果本机是'localhost',服务器的话就是:域名或者IP
  • 参数port:连接的mysql主机的端口,默认是3306
  • 参数database:数据库的名称
  • 参数user:连接的用户名
  • 参数password:连接的密码
  • 参数charset:通信采用的编码方式,推荐使用utf8


  • (3)、对象的方法
  • close()关闭连接
  • commit()提交
  • cursor()返回Cursor(游标)对象,用于执行sql语句并获得结果


  • (4)、Cursor对象
  • 用于执行sql语句,使用频度最高的语句为select、insert、update、delete
  • 获取Cursor对象:调用Connection对象的cursor()方法


cs1=conn.cursor()


  • (5)、对象的方法
  • close()关闭
  • execute(operation [, parameters ])执行语句,返回受影响的行数,主要用于执行insert、update、delete语句,也可以执行create、alter、drop等语句


count = cs1.execute('select * from goods') # 返回是表中数据的个数


  • fetchone()执行查询语句时,获取查询结果集的第一个行数据,返回一个元组
  • fetchall()执行查询时,获取结果集的所有行,一行构成一个元组,再将这些元组装入一个元组返回
  • fetchmany(数量)执行查询时,获取结果集的所有行,一行构成一个元组,再将这些元组装入一个元组返回,也就是元组套元组


image.png


  • (6)、对象的属性
  • rowcount只读属性,表示最近一次execute()执行后受影响的行数
  • connection获得当前连接对象
  • 2.3、python操作sql:查、增、改、删 数据
  • 共用代码


from pymysql import *
def main():
     # 创建Connection连接 
     conn = connect(host='ironman.ren',port=3306,database='jing_dong',user='root',password='456123love',charset='utf8')
     # 获得Cursor(游标)对象
     cursor = conn.cursor()
     """"增删改查的代码"""
     # 关闭Cursor对象
     cursor.close()
     # 关闭Connection对象
     conn.close()
  • (1)、查询数据
    查询数据库某个表的全部数据个数


count = cursor.execute('select * from goods')
print("总数量count=%d"%count)
打印结果:21
  • 查询数表goods里面所有的信息:fetchall()


cursor.execute('select * from goods')
print(cursor.fetchall())
  • 查询数表goods里面部分的信息:fetchmany(数量)


print(cursor.fetchmany(3))
  • 查询数表goods里面一条信息:fetchone()


print(cursor.fetchone())
  • (2)、增加数据:执行insert语句,并返回受影响的行数:添加一条数据


count = cursor.execute('insert into goods values(0,"笨蛋 超极本",5,4,4000,0,0)')
# 提交之前的操作,如果之前已经之执行过多次的execute,那么就都进行提交
conn.commit()
  • (3)、改:更新数据


count = cursor.execute('update goods set name = "超级笨蛋 超极本" where name = "笨蛋 超极本" ')
conn.commit()
  • (4)、删:数据


count = cursor.execute('delete from goods where name="超级笨蛋 超极本" ')
conn.commit()


  • 提示: 除了查询外,增、改、删 都需要  conn.commit()
  • conn.commit(): 提交之前的操作,如果之前已经之执行过多次的execute,那么就都进行提交


  • 2.4、python操作goods表:所有数据、品牌分类、所有的分类


from pymysql import *
class JD(object):
    def __init__(self):
        # 1、创建连接
        self.connection = connect(host='ironman.ren', port=3306, database='jing_dong', user='root', password='456123love',
                       charset='utf8')
        # 2、获取cursor(游标)对象
        self.cursor = self.connection.cursor()
    def __del__(self):
        # 5、关闭游标
        self.cursor.close()
        # 6、关闭数据库连接
        self.connection.close()
    @staticmethod
    def print_munu():
         print("京东商品查询")
         print("1.所有商品")
         print("2.所有商品分类")
         print("3.所有商品品牌分类")
         return input("请输入功能对应的序号:")
    def execute_sql(self,sql):
          count = self.cursor.execute(sql)
          print(count)
          """ 所有数据、品牌分类、所有的分类 """
          for item in self.cursor.fetchall():
                print(item)
    def select_run(self):
         while True:
             num = self.print_munu()
             if num == "1":
                   # 所有商品
                   self.show_all_items()
             elif num == "2":
                  # 所有商品分类
                  self.show_all_cates()
             elif num == "3":
                  # 所有商品品牌分类
                  self.show_all_brand()
    def show_all_items(self):
         # 3、使用游标对象
         # 3.1、查询这个good表
         sql = 'select * from goods'
         self.execute_sql(sql)
    def show_all_brand(self):
         # 3.2、查询这个good表
         sql = 'select * from good_brands'
         self.execute_sql(sql)
    def show_all_cates(self):
         # 3.3、查询这个good表
         sql = 'select * from good_cates'
         self.execute_sql(sql)
def main():
      # 1、创建京东对象
      jd = JD()
      # 2、调用查询
      jd.select_run()
if __name__ == "__main__":
      main()


三、参数化(sql防注入)



  • 3.1、我们来看一个用户搜索商品的例子,根据用户输入的信息进行查询


from pymysql import *
class JD(object):
    def __init__(self):
        # 1、创建连接
        self.connection = connect(host='ironman.ren', port=3306, database='jing_dong', user='root',
                            password='456123love',
                            charset='utf8')
        # 2、获取cursor(游标)对象
        self.cursor = self.connection.cursor()
    def __del__(self):
        # 5、关闭游标
        self.cursor.close()
        # 6、关闭数据库连接
        self.connection.close()
    def select_commodity(self):
        while True:
            select_content = input("请输入搜索的商品内容:")
            params = [select_content]
            self.cursor.execute("select * from goods where name = %s",params)
            for item in self.cursor.fetchall():
                 print(item)
def main():
     jd = JD()
     jd.select_commodity()
if __name__ == "__main__":
     main()
  • 3.2、提一下 3.1中的 def select_commodity(self):方法里面的sql拼接的问题,上面用的安全方式
  • 安全方式:把搜索的内容放到数组里面,在execute()里面,如果要是有多个参数,需要进行参数化,那么params = [数值1, 数值2....],此时sql语句中有多个%s即可 ,sql语句会自动完成,不需要我们来做


select_content = input("请输入搜索的商品内容:")
# 构造参数列表
params = [select_content]
self.cursor.execute("select * from goods where name = %s",params)
  • 不安全方式:如果用户输入:' ' or 7=7,就会查出你数据库所有的数据,假如用户使用的删除操作,很可能把这个表给你全删了😆,sql注入防不胜防


select_content = input("请输入搜索的商品内容:")
sql = "select * from goods where name = %s"% select_content
self.cursor.execute(sql)


image.png

提示:sql语句的参数化,可以有效防止sql注入

友情提示:不要通过sql注入做坏事哦

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
13天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
39 3
|
13天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
42 3
|
13天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE 'log_%';`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
54 2
|
27天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
184 15
|
20天前
|
SQL 关系型数据库 MySQL
数据库数据恢复—Mysql数据库表记录丢失的数据恢复方案
Mysql数据库故障: Mysql数据库表记录丢失。 Mysql数据库故障表现: 1、Mysql数据库表中无任何数据或只有部分数据。 2、客户端无法查询到完整的信息。
|
27天前
|
关系型数据库 MySQL 数据库
数据库数据恢复—MYSQL数据库文件损坏的数据恢复案例
mysql数据库文件ibdata1、MYI、MYD损坏。 故障表现:1、数据库无法进行查询等操作;2、使用mysqlcheck和myisamchk无法修复数据库。
|
MySQL 关系型数据库 数据库
|
MySQL 关系型数据库 RDS
RDS for MySQL CPU 性能问题分析
RDS for MySQL CPU 性能问题分析 RDS for MySQL CPU 使用率高是使用 RDS for MySQL 实例过程中比较常见的一类性能问题。 由于实例 CPU 资源打满会直接导致业务受损,且问题发生过程迅速、临界时间短 统计采集困难、问题发生后统计指标呈反向曲线,加之日常运维过程中问题征兆容易被忽视,非常容易导致用户体感问题突然性强烈,因此在这里我们对 RDS for MySQL 的 CPU 使用率高的原因做一个比较详细的分析说明。
2342 0