【Python】操作MySQL

news2024/10/7 6:50:06

一、Python 操作 Mysql的方式

Python 操作 Mysql 主要包含下面 3 种方式:

  • Python-MySql
    • Python-MySql 由 C 语法打造,接口精炼,性能最棒;但是由于环境依赖多,安装复杂,已停止更新,仅支持 Python2;
  • PyMysql
    • PyMysql 为替代 Python-Mysql 而生,纯 Python 语言编写的 Mysql 操作客户端,安装方便,支持 Python3;
  • SQLAlchemy
    • SQLAlchemy 是一个非常强大的 ORM 框架,不提供底层的数据库操作,主要是通过定义模型对应数据表结构,在 Python Web 编程领域应用广泛

由于 Python-MySql 不支持 Python3,所以本文只谈后 2 种操作方式
 

二、PyMysql

首先,使用 pip 安装依赖 ;

# 安装依赖
pip3 install pymysql

连接数据库,获取数据库连接对象及游标对象;


什么是游标

在 MySQL 中,存储过程或函数中的查询有时会返回多条记录,而使用简单的 SELECT 语句,没有办法得到第一行、下一行或前十行的数据,这时可以使用游标来逐条读取查询结果集中的记录。游标在部分资料中也被称为光标。

 

三、连接数据库

使用 pymysql 中的 connect() 方法,传入数据库的 HOST 地址、端口号、用户名、 密码、待操作数据库的名称,即可以获取数据库的连接对象;然后,再通过数据库连接对象,获取执行数据库具体操作的游标对象


【步骤】:

  • 导入pymysql包
  • 创建数据库链接对象
  • 创建游标对象 
    • 使用cursor() 方法
  • 执行增删改查操作
    • 使用execute()执行单条增删改查
    • 使用executemany()执行多条数据的增删改查
  • 执行完之后将连接对象提交
    • 使用commit()方法
  • 将连接对象关闭
    • 使用close()方法

我们对Class_Linux库中的students表进行增删改查操作:

        原始students表:da033f90b3ad4ae096d09a7efcff9dba.png

 

1)新增

新增包含新增单条数据和新增多条数据

对于单条数据的插入,只需要编写一条插入的 SQL 语句,然后作为参数执行上面游标对象的 execute(sql) 方法,最后使用数据库连接对象的 commit() 方法将数据提交到数据库中


新增单条数据

import pymysql


def connect_mysql():
    # 1、创建数据库链接对象
    mysql_db = pymysql.connect(host='192.168.198.142',
                               port=3306,
                               user='root',
                               password='Nebula@123',
                               database='Class_Linux')
    # 2、创建游标对象
    mysql_course = mysql_db.cursor()

    # 3、执行增删改查操作
    # 使用execute()执行单条增删改查
    mysql_course.execute('insert into students values(NULL,"李白",23,"男",176,1)')
    # 4、执行完之后提交
    mysql_db.commit()
    # 5、将连接对象关闭
    mysql_db.close()


if __name__ == '__main__':
    connect_mysql()

运行之后,去Linux中的students表查看是否插入成功:

95f9b63ac6e44a3bb4c9cfc1a52e82ee.png

插入成功! 


新增多条数据

使用执行游标对象的 executemany() 方法,传入插入的 SQL 语句及 位置变量列表, 可以实现一次插入多条数据


import pymysql


def connect_mysql():

    mysql_db = pymysql.connect(host='192.168.198.142',
                               port=3306,
                               user='root',
                               password='Nebula@123',
                               database='Class_Linux')

    mysql_course = mysql_db.cursor()
    
    # 使用位置变量传参
    insert_query = 'insert into students values(NULL,%s,%s,%s,%s,%s)'
    datas = [("杜甫", 24, "男", 176, 1), ("白居易", 23, "男", 176, 1), ("王安石", 23, "男", 176, 1)]

    # 插入多条数据
    mysql_course.executemany(insert_query, datas)
    mysql_db.commit()
    mysql_db.close()


if __name__ == '__main__':
    connect_mysql()

查询后,插入成功!

6afddc2ef28e4dfa9e98e50fbff519df.png

 

2)查询

查询分为三步,分别是:

  1. 通过游标对象执行具体的 SQL 语句
  2. 通过游标对象,获取到元组数据
  3. 遍历元组数据,查看结果

比如:查看数据表中所有的记录

import pymysql

def connect_mysql():
    mysql_db = pymysql.connect(host='192.168.198.142',
                               port=3306,
                               user='root',
                               password='Nebula@123',
                               database='Class_Linux')

    mysql_course = mysql_db.cursor()

    select_query = 'select * from students'
    mysql_course.execute(select_query)

    # 拿到students表中的的数据,每一条数据都以元组的形式嵌套在一个大元组里
    rows = mysql_course.fetchall()
    print(rows)
    # 打印结果
    for row in rows:
        id = row[0]
        name = row[1]
        age = row[2]
        print('id:', id,'name:',name,'age:',age)


if __name__ == '__main__':
    connect_mysql()

88be9236c74e459fa4b5bd28efb6e54b.png


如果需要按条件查询某一条记录,只需要修改 SQL 语句即可实现; 

import pymysql



def connect_mysql():
    mysql_db = pymysql.connect(host='192.168.198.142',
                               port=3306,
                               user='root',
                               password='Nebula@123',
                               database='Class_Linux')

    mysql_course = mysql_db.cursor()
    # 按id查询
    SQL_QUERY_WITH_CONDITION = "SELECT * FROM students WHERE id={};"
    # 输入数字几就查询那一条数据
    mysql_course.execute(SQL_QUERY_WITH_CONDITION.format(26))

    # 拿到students表中的的数据,每一条数据都以元组的形式嵌套在一个大元组里
    rows = mysql_course.fetchall()
    # 打印结果
    for row in rows:
        id = row[0]
        name = row[1]
        age = row[2]
        print('id:', id,'name:',name,'age:',age)


if __name__ == '__main__':
    connect_mysql()
1d3a918f7c6c4eb0b76bac05378bcb56.png
将查询数据改成交互式:
import pymysql



while True:
    user_input = int(input("请输入您想查询的用户id:"))
    def connect_mysql():
        mysql_db = pymysql.connect(host='192.168.198.142',
                                   port=3306,
                                   user='root',
                                   password='Nebula@123',
                                   database='Class_Linux')

        mysql_course = mysql_db.cursor()
        # 按id查询
        SQL_QUERY_WITH_CONDITION = "SELECT * FROM students WHERE id={};"
        mysql_course.execute(SQL_QUERY_WITH_CONDITION.format(user_input))

        # 拿到students表中的的数据,每一条数据都以元组的形式嵌套在一个大元组里
        rows = mysql_course.fetchall()
        # 打印结果
        for row in rows:
            id = row[0]
            name = row[1]
            age = row[2]
            print('id:', id,'name:',name,'age:',age)


    if __name__ == '__main__':
        # range(28)表示范围在28之内,不包括28
        if user_input in range(28):
            connect_mysql()
        else:
            print("您所输入的id号不正确,请重新输入!")

4c11c9bd40d0453aa2c3e829b474889e.png

 

3)更新

和 新增操作 类似,更新操作也是通过游标对象去执行更新的 SQL 语句,最后利用数 据库连接对象将数据真实更新到数据库中


【步骤】:

  1. 导包
  2. 创建连接对象
  3. 创建游标对象
  4. 执行语句
  5. 提交连接对象
  6. 关闭连接对象

# 1、导包
import pymysql


def connect_mysql():
    # 2、创建连接对象
    mysql_db = pymysql.connect(host='192.168.198.142',
                               port=3306,
                               user='root',
                               password='Nebula@123',
                               database='Class_Linux')
    # 3、创建游标对象
    mysql_course = mysql_db.cursor()
    update_query = 'update students set name="%s",age=%s WHERE id=%s'
    sql_update = update_query % ("王五五", 30, 27)
    # 4、执行语句
    mysql_course.execute(sql_update)
    # 5、提交连接对象
    mysql_db.commit()
    # 6、关闭连接对象
    mysql_db.close()


if __name__ == '__main__':
    connect_mysql()

修改之前:

a8cc932ba1c4454d94ae674c2c2ce557.png

修改之后:

ed77637323df47f085fc6004bb86805a.png

 

4)删除

删除操作同查询、新增操作类似,只需要变更 SQL 语句即可


【步骤】:

  1. 导包
  2. 创建连接对象
  3. 创建游标对象
  4. 执行语句
  5. 释放资源

# 1、导包
import pymysql


def connect_mysql():
    # 2、创建连接对象
    mysql_db = pymysql.connect(host='192.168.198.142',
                               port=3306,
                               user='root',
                               password='Nebula@123',
                               database='Class_Linux')
    # 3、创建游标对象
    mysql_course = mysql_db.cursor()

    # 删除(通过id去删除数据)
    delete_query = 'delete from students where id=%d'
    sql_delete = delete_query % (27)
    # 4、执行sql语句
    mysql_course.execute(sql_delete)
    # 5、释放资源
    mysql_db.commit()
    mysql_db.close()


if __name__ == '__main__':
    connect_mysql()

删除前:

214999f915ea4def9e98924f8d88e231.png

删除后: 021012a7ce964d5b8941200663060704.png

 

四、保存爬取到的数据到MySQL里

之前写的爬取飞卢网站的小说标题,作者,小说类型

import re
import requests

response = requests.get('https://b2.faloo.com/y_0_1.html')


def parse_url():
    # 标题
    div_text1 = re.findall(re.compile(r'<div class="TwoBox02_08">(.*?)</div>'), response.text)
    title_list = []
    for i in div_text1:
        title_list.append(re.findall(re.compile(r'<h1 class="fontSize17andHei" title="(.*?)">'), i)[
                              0])  # 加下标是为了去掉括号[],因为使用?取消贪婪匹配后每一个符合条件的都是列表形式,使用下标可以将每一个小列表中的字符串取出来
    # print(title_list)

    # 作者
    div_text2 = re.findall(re.compile(r'<div class="TwoBox02_09">(.*?)</div>'), response.text)
    author_list = []
    for i in div_text2:
        author_list.append(re.findall(re.compile(r'<a href="//b2.faloo.com/.* title="(.*?)"'), i)[
                               0])  # 加下标是为了去掉括号[],因为使用?取消贪婪匹配后每一个符合条件的都是列表形式,使用下标可以将每一个小列表中的字符串取出来
    # print(author_list)

    # 类型
    div_text3 = re.findall(re.compile(r'<span class="fontSize14andHui">(.*?)</a>'), response.text)
    model_list = []
    for i in div_text3:
        model_list.append(re.findall(re.compile(r'<a href="//b2.faloo.com/l.*" title="(.*?)" target="_blank">'), i)[
                              0])  # 加下标是为了去掉括号[],因为使用?取消贪婪匹配后每一个符合条件的都是列表形式,使用下标可以将每一个小列表中的字符串取出来
    # print(model_list)

    # 将爬取到的内容合并
    multi_list = map(list, zip(title_list, author_list, model_list))
    all_list = list(multi_list)
    # print(all_list)
    return all_list


def write_data():
    with open('./novel.txt', 'w', encoding='utf-8') as fw:
        fw.write('书名                            作者          类型\n')
        for i in parse_url():
            fw.write('     '.join(i) + '\n')


if __name__ == '__main__':
    print(parse_url())
    write_data()

新建spider_and_pymysql_2.py文件

import pymysql
# 导入自定义模块
from spider.Feilu_spider4 import parse_url

# 插入数据
def insert_info(all_list):
    mysql_db = pymysql.connect(host='192.168.198.142',
                               port=3306,
                               user='root',
                               password='Nebula@123',
                               database='Class_Linux')

    mysql_course = mysql_db.cursor()
    # db = connect_mysql()[0]
    # course = connect_mysql()[1]
    # 创建表
    create_table_sql = "create table if not exists novel_info(id int NOT NULL auto_increment primary key," \
                       "novel_name varchar(100)," \
                       "novel_author varchar(30)," \
                       "novel_type varchar(30))"  
    mysql_course.execute(create_table_sql)
    # 插入多条数据
    try:
        sql_insert = 'insert into novel_info values(NULL,"%s","%s","%s");'
        mysql_course.executemany(sql_insert, all_list)
        print("爬取到数据,开始插入")
        print(all_list)
        mysql_db.commit()
        print("数据插入成功!")
    except Exception as e:
        print(e, "数据插入失败!")
    print("操作成功!")


if __name__ == '__main__':
    insert_info(parse_url())

去MySQL查看发现插入成功!5634dda9abf34e6ab63150057477c8aa.png


【可能出现的报错!】

如果你的程序没有报错,去MySQL查看发现id被占了但是没有数据,例如下面的情况


查看表,发现没有数据:1c0852ba8ebe4f539e60cdc58f60c8ce.png

随便插入一条数据;a9b70982f9264731be276038dfb1a7cf.png 再查看,发现id被占了 

25fa809df6d94bb78fddb1aa11413c54.png


这可能是因为在我的代码里,我将创建连接对象和创建游标对象单独封装成立一个函数,在insert_info函数中,没有重新创建连接对象和创建游标对象,而是利用return调用了它的返回值,如果你也有这样的问题,就请给插入数据的函数重新创建连接对象和创建游标对象,下面是错误的代码:

import pymysql
# 导入自定义模块
from spider.Feilu_spider4 import parse_url


# 连接数据库
def connect_mysql():
    mysql_db = pymysql.connect(host='192.168.198.142',
                               port=3306,
                               user='root',
                               password='Nebula@123',
                               database='Class_Linux')

    mysql_course = mysql_db.cursor()
    return mysql_db, mysql_course


# 插入数据
def insert_info(all_list):
    db = connect_mysql()[0]
    course = connect_mysql()[1]
    # 创建表
    create_table_sql = "create table if not exists novel_info(id int NOT NULL auto_increment primary key," \
                       "novel_name varchar(100)," \
                       "novel_author varchar(30)," \
                       "novel_type varchar(30))"  # 为啥加个)就行了?????
    course.execute(create_table_sql)
    # 插入多条数据
    try:
        sql_insert = 'insert into novel_info values(NULL,"%s","%s","%s");'
        course.executemany(sql_insert, all_list)
        print("爬取到数据,开始插入")
        print(all_list)
        db.commit()
        print("数据插入成功!")
    except Exception as e:
        print(e, "数据插入失败!")
    print("操作成功!")


if __name__ == '__main__':
    # connect_mysql()
    insert_info(parse_url())

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/483046.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记一次我的漏洞挖掘实战——某公司的SQL注入漏洞

目录 一、前言 二、挖掘过程 1.谷歌语法随机搜索 2.进入网站 3.注入点检测 3.SQLMAP爆破 &#xff08;1&#xff09;爆库 &#xff08;2&#xff09;爆表 &#xff08;3&#xff09;爆字段 三、总结 一、前言 我是在漏洞盒子上提交的漏洞&#xff0c;上面有一个项目叫…

【远程工具】- Tabby 下载、安装、使用、配置【ssh/Serial】-免安装、解压即用

目录 一、Tabby 概述 二、Tabby 下载、安装 三、Tabby 的使用  &#x1f449;3.1 使用SSH协议连接Linux开发主机  &#x1f449;3.2 使用Serial(串口)协议连接开发板 一、Tabby 概述 在远程终端工具中&#xff0c;secureCrt 和 XShell 是两款比较有名的远程工具&#xff0c;但…

矩阵求逆方法

1.待定系数法 矩阵A 1, 2 -1,-3 假设所求的逆矩阵为 a,b c,d 则 从而可以得出方程组 a 2c 1 b 2d 0 -a - 3c 0 -b - 3d 1 解得 a3; b2; c -1; d -1 2.伴随矩阵求逆矩阵 伴随矩阵是矩阵元素所对应的代数余子式&#xff0c;所构成的矩阵&#xff0c;转置后得到的新矩阵…

图的存储--邻接矩阵/边集数组/邻接表/链式邻接表/链式前向星

邻接矩阵 使用二维数组w[u][v]存储点u到点v的边的权值。一般应用在点数不多的稠密图 时间复杂度&#xff1a;O(n2) 空间复杂度&#xff1a;O(n2) int w[N][N]; // edge int vis[N]; // visitedvoid dfs(int u){vis[u] true;for(int v 1; v < n; v)if(w[u][v]){prin…

Java 基础进阶篇(六)—— 面向对象三大特征之三:多态

文章目录 一、多态的概述二、多态中成员访问特点 ★三、多态的优势与劣势四、多态下的类型转换4.2 自动类型转换&#xff08;从子到父&#xff09;4.2 强制类型转换&#xff08;从父到子&#xff09;4.3 instanceof 关键字 一、多态的概述 多态&#xff1a;是指执行同一个行为…

自动驾驶——最优控制算法里卡提方程推导【连续系统】

1. Why use the Riccati equation&#xff1f; Q、R就是需要设计的半正定矩阵和正定矩阵。考虑根据实车的情况去标定此参数&#xff0c;从理论和工程层面去理解&#xff0c;如果增大Q、减小R&#xff0c;则此时控制系统响应速度比较快速&#xff08;比较剧烈&#xff09;&…

[SpringBoot]什么是服务器前后端的一个流程图bmi练习案例

前点: 服务器&#xff1a; 服务器就是一台高性能的电脑, 在电脑上安装了提供XXX服务的软件, 这台电脑就可以称为XXX服务器 - 举例: - 数据库服务器: 在电脑上安装了提供数据增删改查服务的软件(DBMS) - 邮件服务器: 在电脑上安装了提供邮件收发服务的软件 - FTP服务器: …

普通的2D Average pooling是怎么进行backward的呢?

二维平均池层计算损失相对于其输入张量的梯度&#xff0c;方法是将损失相对于输出张量的梯度均分在输入子区域&#xff0c;这些子区域在前向传播中被用来计算平均值。 由于平均集合计算的是每个输入子区域的平均值&#xff0c;所以子区域中的每个元素对平均值的贡献是相同的。…

Java Servlet_HTTP

今日内容 零、 复习昨日 一、Servlet 二、HTTP 三、HttpServlet 零、 复习昨日 见晨考 一、Servlet 1.1 介绍 javaweb开发,就是需要服务器接收前端发送的请求,以及请求中的数据,经过处理(jdbc操作),然后向浏览器做出响应. 我们要想在服务器中写java代码来接收请求,做出响应,我…

SignOff Criteria——AOCV(Advanced OCV) introduction

文章目录 1. O v e r v i e w Overview Overview2. A O C V P r i n c i p l e I n t r o d u c t i o n AOCV\ Principle\ Introduction AOCV Principle Introduction2.1 G B A − A O C V GBA-AOCV GBA−AOCV2.1.1 A b o u t L o g i c a l D e p t h About\ Logical\ De…

第六章 Iptables与Firewalld防火墙

第六章 Iptables与Firewalld防火墙 一、Iptables 1、策略与规则链 &#xff08;1&#xff09;、防火墙策略规则的设置 一种是“通”即放行&#xff0c;另一种是“堵”即阻止。 当防火墙的默认策略为拒绝时&#xff08;堵&#xff09;&#xff0c;就要设置允许规则通&#x…

NECCS|全国大学生英语竞赛C类|听力|短对话|14:20~15:30

目录 一、短对话 1. 定位词 2. 场景词汇 &#xff08;1&#xff09;餐馆用餐 &#xff08;2&#xff09;商场用语 &#xff08;3&#xff09;校园用语 &#xff08;4&#xff09;图书馆用语 二、题目类型 1. 人物类 考点聚焦 2. 地点类 主要涉及 3. 数字类 4. 主题…

【数据库】JDBC编程

前言 小亭子正在努力的学习编程&#xff0c;接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟&#xff0c;如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话&#xff0c;烦请点赞关注支持一波, 感激不尽~~ 目录 前言 什么是JDBC&#xff1f; JDBC工…

sql注入(三)绕过方法及防御手段

一、sql注入的绕过方法 1.注释符过滤绕过 常用的注释符有&#xff1a; 1&#xff09;-- 注释内容 2&#xff09;# 注释内容 3&#xff09;/* 注释内容 */ 绕过方法 构造闭合&#xff1a; ?id1 and sql语句 and 11 这样接收源码前面的引号被 id1 中的后引号所闭合&…

关于MPU的笔记

MPU&#xff08;memory protection unit&#xff09;内存保护单元。这些系统必须提供一种机制来保证正在运行的任务不破坏其他任务的操作。即要防止系统资源和其他一些任务不受非法访问。嵌入式系统有专门的硬件来检测和限制系统资源的访问。它能保证资源的所有权&#xff0c;任…

unity 性能优化之画质分级

如果你的游戏兼容多平台&#xff0c;或者当前平台的设备也有硬件差距&#xff0c;比如低端设备就是带不动你的画质&#xff0c;无论如何你如何优化就是带不动。这种情况下&#xff0c;我们可以考虑对画质进行分级&#xff0c;减少一些特性&#xff0c;来提高运行质量。接下来我…

JavaWeb《HTML基础标签》

本笔记学习于Acwing平台 MDN官方文档https://developer.mozilla.org/zh-CN/ 目录 1. html文件结构 2. 文本标签 3. 图片 4. 音频和视频 5. 超链接 6. 表单 7. 列表 8. 表格 9. 语义标签 10. 特殊符号 1. html文件结构 文档结构 html的所有标签为树形结构&#xff…

AI模型推理(3)——ModelMesh使用

参考&#xff1a; ModelMesh installation - KServe Documentation Website ModelMesh Overview - KServe Documentation Website 前言 Kserve提供了“Serverless”和“ModelMesh”两种安装模式。其中Serverless是通过Knative组件实现动态扩缩容等功能。而ModelMesh则是另一…

华南X99F8D开不了机——主板出现错误码67的解决方案

华南X99F8D开不了机——主板出现错误码67的解决方案 前言 笔者的双路e5&#xff1a;大数据双路e5主机搭建&#xff1a;2696v3256g内存 配置&#xff1a; 主板&#xff1a;x99f8d CPU&#xff1a;e5 2696v3 *2 【36核72线程】 内存条&#xff1a;DDR4 ECC 32G *8 【256G】 显…

Nginx + LVS + KeepAlived实现高可用集群

文章目录 一、名词解释1、高可用集群2、LVS3、Keepalived 二、搭建流程1、安装Docker2、安装Nginx3、安装Keepalived4、编写nginx_check.sh脚本 一、名词解释 1、高可用集群 对于中小型互联网公司&#xff0c;产品所承受的请求量还是比较低的&#xff0c;所以一般使用单节点N…