【Python】操作MySQL

一、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表:【Python】操作MySQL_第1张图片

 

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表查看是否插入成功:

【Python】操作MySQL_第2张图片

插入成功! 


新增多条数据

使用执行游标对象的 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()

查询后,插入成功!

【Python】操作MySQL_第3张图片

 

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()

【Python】操作MySQL_第4张图片


如果需要按条件查询某一条记录,只需要修改 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号不正确,请重新输入!")

【Python】操作MySQL_第5张图片

 

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()

修改之前:

【Python】操作MySQL_第6张图片

修改之后:

【Python】操作MySQL_第7张图片

 

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()

删除前:

【Python】操作MySQL_第8张图片

删除后: 【Python】操作MySQL_第9张图片

 

四、保存爬取到的数据到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'
(.*?)
'), response.text) title_list = [] for i in div_text1: title_list.append(re.findall(re.compile(r'

'), i)[ 0]) # 加下标是为了去掉括号[],因为使用?取消贪婪匹配后每一个符合条件的都是列表形式,使用下标可以将每一个小列表中的字符串取出来 # print(title_list) # 作者 div_text2 = re.findall(re.compile(r'
(.*?)
'), response.text) author_list = [] for i in div_text2: author_list.append(re.findall(re.compile(r'(.*?)'), response.text) model_list = [] for i in div_text3: model_list.append(re.findall(re.compile(r''), 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查看发现插入成功!【Python】操作MySQL_第10张图片


【可能出现的报错!】

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


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

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

【Python】操作MySQL_第11张图片


这可能是因为在我的代码里,我将创建连接对象和创建游标对象单独封装成立一个函数,在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())

 

 

 

你可能感兴趣的:(Python,mysql,python,数据库)