太全了!用Python操作MySQL的使用教程集锦!转载

原创
小哥 3年前 (2022-10-16) 阅读数 78 #大杂烩
点击上面的“素食”,点击上面的“素食研究”,点击上面的“烹饪”Python“,选择”明星“公共号码”,选择“明星”公共号码“,选择”明星“公共号码

超级无敌干货,先送到!超级无与伦比的干货,首发!

源丨互联网源丨WEB源丨网络源丨互联网

一. 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使用了两种主要方法。主要使用了两种方法。主要使用了两种方法。主要采用了两种方法。

  1. 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模块的占位符似乎是一个问号(?)。因此,在使用其他数据库时,最好仔细阅读文档。Welcome to PyMySQL’s documentation

三. 数据库连接池数据库连接池数据库连接池

上述方法有一个问题,单线程外壳可以满足单线程外壳满足单线程外壳可以满足,程序需要频繁创建和释放连接才能完成对数据库的操作,那么,我们的程序我们的程序我们的过程/在多线程情况下,脚本可能会导致什么问题?此时,我们就需要使用数据库连接池数据库连接池数据库连接池来解决这个问题!

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, 

)

    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: 静态方法可以封装在类中,静态方法可以封装在类中,方便使用

推荐阅读:
入门: 最完整的零基学习最全面的零基学习最完整的零基学习Python的问题  | 从零开始学习从零基础学习从零基础学习8个月的Python  | 实战项目 |学Python这是捷径这是捷径就是这条捷径
干货:爬行豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析最佳球员分析 |   从万众期待到口碑惨败!唐探3令人失望  | 笑新一天图龙记笑新一天图龙集 | 谜语之王回答灯谜之王灯谜之王谜语之王 |用Python人山人海素描图人山人海素描图人山人海 Dishonor太火了,我用机器学习做了一个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python日常酷跑游戏日常酷跑游戏日常酷跑游戏!
AI: 会写诗的机器人会写诗的机器人会写诗的机器人 | 给图片上色给图片上色给图片上色 | 预测收入 | 《耻辱》太火了,我用机器学习做了一部迷你推荐系统电影
小工具: Pdf转Word易于修复表单和水印!易于处理的表单和水印!易于修复表单和水印!简单的表格和水印! | 一键把html将页面另存为网页另存为网页另存为pdf!|  再见PDF提款费!提款费!提款费!提款费用! | 用90构建最强大的代码行构建最强大的代码行构建最强大的代码行PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一个固定的低成本机票提醒!制作一张别针的低价机票提醒! |60代码行做了一个语音墙纸切换,天天见女士!

年度弹出文案年度弹出文案年度爆炸性文案

  • 1). 卧槽!Pdf转Word用Python轻松搞定 !

  • 2).学Python闻起来好香!我用100一行代码做了一个网站,帮助人们做了一行代码,做了一个网站,帮助了人们做了一行代码,帮助了人们PS旅行图片赚鸡腿吃旅行图片赚鸡腿

  • 3).第一次播放量过亿,火爆全网,我分析了《波妹》,发现了这些秘密

  • 4). 80一行行代码!使用Python让救济金做正确的事做做的人做好事的人A梦分身

  • 5).你必须掌握的东西你必须掌握20个python代码,简短而紧凑,无限有用的代码,简短而紧凑,无休止的使用代码,简短而紧凑,无休止的使用

  • 6). 30个Python古怪技能集古怪小贴士收藏古怪技能集

  • 7). 我总结的80《菜鸟学习专页》《菜鸟学习专页》《菜鸟学习》Python精选干货.pdf》,都是干货

  • 8). 再见Python!我要学Go了!2500词深度分析词深度分析词深度分析 !

  • 9).发现一只舔狗的福利!这Python爬虫神器太酷了,不能自动下载女孩的照片

点击阅读原文点击查看点击点击阅读点击阅读原文点击查看B放我鸽子看录像!站在我的录像带上!在视频里放我鸽子!站在我的录像带上!

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门