当前位置:

首页 > 编程开发 > Python操作MySQL数据库的关键步骤及方法

Python操作MySQL数据库的关键步骤及方法

一.python操作数据库介绍Python标准数据库接口为PythonDB-API,PythonDB-API为开发人员提供了数据库应用编程接口。Python数据库接口支持非常多的数据库,你可以选择适合你项目的数据库:GadFlymSQLMySQLPostgreSQLMicrosoftSQLServer2000InformixInterbaseOracleSybase…你可以访问Python数据库接口及API查看详细的支持数据库列表。不同的数据库你需要下载不同的DBAPI模块,例如你需要访问Oracle数据

本文目录

    一. python操作数据库介绍

    Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口。Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库:

    • GadFly

    • mSQL

    • MySQL

    • PostgreSQL

    • Microsoft SQL Server 2000

    • Informix

    • Interbase

    • Oracle

    • Sybase …

    你可以访问Python数据库接口及API查看详细的支持数据库列表。

    不同的数据库你需要下载不同的DB API模块,例如你需要访问Oracle数据库和Mysql数据,你需要下载Oracle和MySQL数据库模块。

    DB-API 是一个规范. 它定义了一系列必须的对象和数据库存取方式, 以便为各种各样的底层数据库系统和多种多样的数据库接口程序提供一致的访问接口 。

    Python的DB-API,为大多数的数据库实现了接口,使用它连接各数据库后,就可以用相同的方式操作各数据库。

    Python DB-API使用流程:

    • 引入 API 模块。

    • 获取与数据库的连接。

    • 执行SQL语句和存储过程。

    • 关闭数据库连接。

    二. python操作MySQL模块

    Python操作MySQL主要使用两种方式:

    DB模块(原生SQL)

    • PyMySQL(支持python2.x/3.x)

    • MySQLdb(目前仅支持python2.x)

    ORM框架

    • SQLAchemy

    2.1 PyMySQL模块

    本文主要介绍PyMySQL模块,MySQLdb使用方式类似

    2.1.1 安装PyMySQL

    PyMySQL是一个Python编写的MySQL驱动程序,让我们可以用Python语言操作MySQL数据库。

    pip install PyMySQL
    2.2 基本使用
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "shuke"
    # Date: 2018/5/13
    import pymysql
    # 创建连接
    conn = pymysql.connect(host="127.0.0.1", port=3306, user='zff', passwd='zff123', db='zff', charset='utf8mb4')
    # 创建游标(查询数据返回为元组格式)
    # cursor = conn.cursor()
    # 创建游标(查询数据返回为字典格式)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    # 1. 执行SQL,返回受影响的行数
    effect_row1 = cursor.execute("select * from USER")
    # 2. 执行SQL,返回受影响的行数,一次插入多行数据
    effect_row2 = cursor.executemany("insert into USER (NAME) values(%s)", [("jack"), ("boom"), ("lucy")])# 3
    # 查询所有数据,返回数据为元组格式
    result = cursor.fetchall()
    # 增/删/改均需要进行commit提交,进行保存
    conn.commit()
    # 关闭游标
    cursor.close()
    # 关闭连接
    conn.close()
    print(result)
    """
    [{'id': 6, 'name': 'boom'}, {'id': 5, 'name': 'jack'}, {'id': 7, 'name': 'lucy'}, {'id': 4, 'name': 'tome'}, {'id': 3, 'name': 'zff'}, {'id': 1, 'name': 'zhaofengfeng'}, {'id': 2, 'name': 'zhaofengfeng02'}]
    """
    2.3 获取最新创建的数据自增ID
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "shuke"
    # Date: 2018/5/13
    import pymysql
    # 创建连接
    conn = pymysql.connect(host="127.0.0.1", port=3306, user='zff', passwd='zff123', db='zff', charset='utf8mb4')
    # 创建游标(查询数据返回为元组格式)
    cursor = conn.cursor()
    # 获取新创建数据自增ID
    effect_row = cursor.executemany("insert into USER (NAME)values(%s)", [("eric")])
    # 增删改均需要进行commit提交
    conn.commit()
    # 关闭游标
    cursor.close()
    # 关闭连接
    conn.close()
    new_id = cursor.lastrowid
    print(new_id)
    """
    8
    """
    2.4 查询操作
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "shuke"
    # Date: 2018/5/13
    import pymysql
    # 创建连接
    conn = pymysql.connect(host="127.0.0.1", port=3306, user='zff', passwd='zff123', db='zff', charset='utf8mb4')
    # 创建游标
    cursor = conn.cursor()
    cursor.execute("select * from USER")
    # 获取第一行数据
    row_1 = cursor.fetchone()
    # 获取前n行数据
    row_2 = cursor.fetchmany(3)
    #
    # # 获取所有数据
    row_3 = cursor.fetchall()
    # 关闭游标
    cursor.close()
    # 关闭连接
    conn.close()
    print(row_1)
    print(row_2)
    print(row_3)

    ⚠️ 在fetch数据时按照顺序进行,可以使用cursor.scroll(num,mode)来移动游标位置,如:

    • cursor.scroll(1,mode='relative')  # 相对当前位置移动

    • cursor.scroll(2,mode='absolute')  # 相对绝对位置移动

    2.5 防止SQL注入
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "shuke"
    # Date: 2018/5/13
    import pymysql
    # 创建连接
    conn = pymysql.connect(host="127.0.0.1", port=3306, user='zff', passwd='zff123', db='zff', charset='utf8mb4')
    # 创建游标
    cursor = conn.cursor()
    # 存在sql注入情况(不要用格式化字符串的方式拼接SQL)
    sql = "insert into USER (NAME) values('%s')" % ('zhangsan',)
    effect_row = cursor.execute(sql)
    # 正确方式一
    # execute函数接受一个元组/列表作为SQL参数,元素个数只能有1个
    sql = "insert into USER (NAME) values(%s)"
    effect_row1 = cursor.execute(sql, ['wang6'])
    effect_row2 = cursor.execute(sql, ('wang7',))
    # 正确方式二
    sql = "insert into USER (NAME) values(%(name)s)"
    effect_row1 = cursor.execute(sql, {'name': 'wudalang'})
    # 写入插入多行数据
    effect_row2 = cursor.executemany("insert into USER (NAME) values(%s)", [('ermazi'), ('dianxiaoer')])
    # 提交
    conn.commit()
    # 关闭游标
    cursor.close()
    # 关闭连接
    conn.close()

    这样,SQL操作就更安全了。如果需要更详细的文档参考PyMySQL文档吧。不过好像这些SQL数据库的实现还不太一样,PyMySQL的参数占位符使用%s这样的C格式化符,而Python自带的sqlite3模块的占位符好像是问号(?)。因此在使用其他数据库的时候还是仔细阅读文档吧。

    三. 数据库连接池

    上文中的方式存在一个问题,单线程情况下可以满足,程序需要频繁的创建释放连接来完成对数据库的操作,那么,我们的程序/脚本在多线程情况下会引发什么问题呢?此时,我们就需要使用数据库连接池来解决这个问题!

    3.1 DBUtils模块

    DBUtils是Python的一个用于实现数据库连接池的模块。

    此连接池有两种连接模式:

    • 为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程再次使用。当线程终止时,连接才会自动关闭

    • 创建一批连接到连接池,供所有线程共享使用(推荐使用)

    3.2 模式一
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "shuke"
    # Date: 2018/5/13
    from DBUtils.PersistentDB import PersistentDB
    import pymysql
    POOL = PersistentDB(
     creator=pymysql,# 使用链接数据库的模块
     maxusage=None,# 一个链接最多被重复使用的次数,None表示无限制
     setsession=[],# 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
     ping=0,
     # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
     closeable=False,
     # 如果为False时, conn.close() 实际上被忽略,供下次使用,再线程关闭时,才会自动关闭链接。如果为True时, conn.close()则关闭链接,那么再次调用pool.connection时就会报错,因为已经真的关闭了连接(pool.steady_connection()可以获取一个新的链接)
     threadlocal=None,# 本线程独享值得对象,用于保存链接对象,如果链接对象被重置
     host='127.0.0.1',
     port=3306,
     user='zff',
     password='zff123',
     database='zff',
     charset='utf8',
    )
    def func():
     conn = POOL.connection(shareable=False)
     cursor = conn.cursor()
     cursor.execute('select * from USER')
     result = cursor.fetchall()
     cursor.close()
     conn.close()
     return result
    result = func()
    print(result)
    3.2 模式二
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "shuke"
    # Date: 2018/5/13
    import time
    import pymysql
    import threading
    from DBUtils.PooledDB import PooledDB, SharedDBConnection
    POOL = PooledDB(
     creator=pymysql,# 使用链接数据库的模块
     maxconnections=6,# 连接池允许的最大连接数,0和None表示不限制连接数
     mincached=2,# 初始化时,链接池中至少创建的空闲的链接,0表示不创建
     maxcached=5,# 链接池中最多闲置的链接,0和None不限制
     maxshared=3,
     # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
     blocking=True,# 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
     maxusage=None,# 一个链接最多被重复使用的次数,None表示无限制
     setsession=[],# 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
     ping=0,
     # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
     host='127.0.0.1',
     port=3306,
     user='zff',
     password='zff123',
     database='zff',
     charset='utf8'
    )
    def func():
     # 检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise TooManyConnections异常
     # 否则
     # 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。
     # 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。
     # 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。
     # 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。
     conn = POOL.connection()
     # print('连接被拿走了', conn._con)
     # print('池子里目前有', POOL._idle_cache, 'rn')
     cursor = conn.cursor()
     cursor.execute('select * from USER')
     result = cursor.fetchall()
     conn.close()
     return result
    result = func()
    print(result)

    ⚠️ 由于pymysql、MySQLdb等threadsafety值为1,所以该模式连接池中的线程会被所有线程共享,因此是线程安全的。如果没有连接池,使用pymysql来连接数据库时,单线程应用完全没有问题,但如果涉及到多线程应用那么就需要加锁,一旦加锁那么连接势必就会排队等待,当请求比较多时,性能就会降低了。

    3.3 加锁
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "shuke"
    # Date: 2018/5/13
    import pymysql
    import threading
    from threading import RLock
    LOCK = RLock()
    CONN = pymysql.connect(host='127.0.0.1',
    port=3306,
    user='zff',
    password='zff123',
    database='zff',
    charset='utf8')
    def task(arg):
     with LOCK:
     cursor = CONN.cursor()
     cursor.execute('select * from USER ')
     result = cursor.fetchall()
     cursor.close()
     print(result)
    for i in range(10):
     t = threading.Thread(target=task, args=(i,))
     t.start()
    3.4 无锁(报错)
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    # __author__ = "shuke"
    # Date: 2018/5/13
    import pymysql
    import threading
    CONN = pymysql.connect(host='127.0.0.1',
    port=3306,
    user='zff',
    password='zff123',
    database='zff',
    charset='utf8')
    def task(arg):
     cursor = CONN.cursor()
     cursor.execute('select * from USER ')
     # cursor.execute('select sleep(10)')
     result = cursor.fetchall()
     cursor.close()
     print(result)
    for i in range(10):
     t = threading.Thread(target=task, args=(i,))
     t.start()

    此时可以在数据库中查看连接情况: show status like 'Threads%';

    四. 数据库连接池结合pymsql使用

    # cat sql_helper.py
    import pymysql
    import threading
    from DBUtils.PooledDB import PooledDB, SharedDBConnection
    POOL = PooledDB(
     creator=pymysql,# 使用链接数据库的模块
     maxconnections=20,# 连接池允许的最大连接数,0和None表示不限制连接数
     mincached=2,# 初始化时,链接池中至少创建的空闲的链接,0表示不创建
     maxcached=5,# 链接池中最多闲置的链接,0和None不限制
     #maxshared=3,# 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
     blocking=True,# 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
     maxusage=None,# 一个链接最多被重复使用的次数,None表示无限制
     setsession=[],# 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
     ping=0,
     # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
     host='192.168.11.38',
     port=3306,
     user='root',
     passwd='apNXgF6RDitFtDQx',
     db='m2day03db',
     charset='utf8'
    )
    def connect():
     # 创建连接
     # conn = pymysql.connect(host='192.168.11.38', port=3306, user='root', passwd='apNXgF6RDitFtDQx', db='m2day03db')
     conn = POOL.connection()
     # 创建游标
     cursor = conn.cursor(pymysql.cursors.DictCursor)
     return conn,cursor
    def close(conn,cursor):
     # 关闭游标
     cursor.close()
     # 关闭连接
     conn.close()
    def fetch_one(sql,args):
     conn,cursor = connect()
     # 执行SQL,并返回收影响行数
     effect_row = cursor.execute(sql,args)
     result = cursor.fetchone()
     close(conn,cursor)
     return result
    def fetch_all(sql,args):
     conn, cursor = connect()
     # 执行SQL,并返回收影响行数
     cursor.execute(sql,args)
     result = cursor.fetchall()
     close(conn, cursor)
     return result
    def insert(sql,args):
     """
     创建数据
     :param sql: 含有占位符的SQL
     :return:
     """
     conn, cursor = connect()
     # 执行SQL,并返回收影响行数
     effect_row = cursor.execute(sql,args)
     conn.commit()
     close(conn, cursor)
    def delete(sql,args):
     """
     创建数据
     :param sql: 含有占位符的SQL
     :return:
     """
     conn, cursor = connect()
     # 执行SQL,并返回收影响行数
     effect_row = cursor.execute(sql,args)
     conn.commit()
     close(conn, cursor)
     return effect_row
    def update(sql,args):
     conn, cursor = connect()
     # 执行SQL,并返回收影响行数
     effect_row = cursor.execute(sql, args)
     conn.commit()
     close(conn, cursor)
     return effect_row

    PS: 可以利用静态方法封装到一个类中,方便使用

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Python MySQL
    相关文章 更多
    navicat导入数据库步骤详解及常见问题处理教程
    navicat导入数据库步骤详解及常见问题处理教程

    详解Navicat导入数据库的标准步骤,涵盖SQL脚本执行与CSV数据导入两种核心场景。针对导入过程中常见的字符集乱码、主键冲突及外键约束错误,提供具体的设置方法与修复建议,确保数据迁移准确无误。

    python删除一个列表里的重复元素的方法与代码示例
    python删除一个列表里的重复元素的方法与代码示例

    学习如何使用Python高效删除列表中的重复元素。本文提供5种常见方法的代码示例,涵盖保持顺序与不保持顺序的场景,适合初学者和进阶开发者参考。

    SQL主键约束和唯一约束有什么区别
    SQL主键约束和唯一约束有什么区别

    深入理解SQL PRIMARY KEY与UNIQUE约束的区别。文章从行标识与重复限制的目标出发,详解主键的非空特性、外键引用角色以及多数据库对NULL值的处理差异。结合users表实战示例,指导开发者如何根据字段稳定性与业务语义合理选择约束类型,避免设计误区。

    SQL约束有哪些类型及作用
    SQL约束有哪些类型及作用

    刚开始设计关系型数据库?了解PRIMARY KEY、FOREIGN KEY、UNIQUE、NOT NULL、CHECK、DEFAULT等约束的作用、语法和排错方法。本文以PostgreSQL语法为主,结合用户订单场景,清晰展示如何防止脏数据并处理常见约束冲突。

    SQL游标常见错误排查:死锁与资源未释放问题
    SQL游标常见错误排查:死锁与资源未释放问题

    深入解析SQL游标导致的死锁与资源未释放问题。通过PostgreSQL与MySQL语法对比,展示如何识别长事务持锁、分析锁等待链,并提供短事务提交、异常清理及批量处理的最佳实践,确保数据库连接与锁资源及时释放。

    SQL中怎么创建和删除约束
    SQL中怎么创建和删除约束

    后端开发者在维护数据库时,常需对现有表添加主键、唯一或外键约束。若直接执行ADD CONSTRAINT,往往因存量数据不合规导致报错。本文详解操作前的数据清洗步骤、标准SQL语法及MySQL等特殊写法,帮助你在生产环境安全完成结构变更。

    Python写接口的步骤及完整代码示例
    Python写接口的步骤及完整代码示例

    详细讲解使用Python编写Web接口的核心步骤与完整代码示例,涵盖环境准备、路由定义、数据校验、服务启动及调试测试方法。

    SQL分组统计查询:GROUP BY与HAVING子句用法示例
    SQL分组统计查询:GROUP BY与HAVING子句用法示例

    针对 SQL 初学者的分组统计实战指南。深入解析 GROUP BY 分组机制、WHERE 与 HAVING 的执行时机差异,以及 COUNT 函数对 NULL 值的处理逻辑。通过具体代码示例演示如何正确筛选聚合结果,并排查因 JOIN 连接导致的统计数据异常,提升报表准确性。

    SQL Server与MySQL游标基本语法及完整代码示例
    SQL Server与MySQL游标基本语法及完整代码示例

    本文详细对比SQL Server和MySQL中游标的基本用法。从DECLARE声明到FETCH遍历,再到CLOSE关闭与DEALLOCATE/Handler清理,解析两者在语法结构、变量接收及异常处理上的核心差异。通过标准代码示例展示如何安全使用游标,避免资源泄漏,适用于需要进行数据库存储过程开发或跨平台迁移的开发者。

    codex怎么读取word文档及docx文件操作教程
    codex怎么读取word文档及docx文件操作教程

    介绍如何利用编程工具读取和解析Word文档(docx格式),涵盖基础文本提取代码示例、结构化数据处理逻辑,以及处理复杂排版时的技术局限与替代方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。