Python怎样操作MariaDB数据库?mariadb连接器

python操作mariadb应优先选择pymysql或mysql-connector-python,pymysql因纯python实现、安装简便、社区活跃而更适合大多数场景;2. 防止sql注入必须使用参数化查询,通过占位符(如%s)与参数元组分离sql结构与数据,避免恶意输入篡改语句;3. 事务处理需手动控制,通过conn.autocommit=false禁用自动提交,在try块中执行操作,成功则conn.commit()提交,异常则conn.rollback()回滚,确保数据一致性;4. 使用dictcursor可使查询结果以字典形式返回,提升数据处理便利性;5. 实际操作流程包括安装库、连接数据库、创建游标、执行sql、处理结果及关闭资源,全程需用try-except-finally确保连接正确释放。

Python怎样操作MariaDB数据库?mariadb连接器

Python操作MariaDB数据库,核心在于使用合适的数据库连接器(或者说驱动)。这些连接器提供了标准化的API,让你能够像与任何其他数据库交互一样,建立连接、执行SQL查询、处理结果集,并管理事务。最常用的纯Python连接器是

PyMySQL

,它轻量且易于上手;当然,也有官方的

mysql-connector-python

,功能更全面些。

解决方案

要用Python来操作MariaDB,我们通常会遵循一套比较标准的流程,这包括安装连接库、建立连接、创建游标、执行SQL命令、处理结果,最后关闭连接。这听起来可能有点流程化,但实际操作起来,你会发现它非常直观。

首先,你需要安装一个数据库连接库。我个人比较常用

PyMySQL

,因为它纯Python实现,依赖少,而且社区活跃。你可以用pip来安装它:

立即学习“Python免费学习笔记(深入)”;

pip install PyMySQL

安装好之后,就可以开始编写代码了。连接数据库是第一步,你需要提供数据库的主机地址、用户名、密码和数据库名。字符集也很重要,避免出现乱码问题,通常设置为

utf8mb4

是个不错的选择,能支持更广的字符范围,比如表情符号。

import pymysql# 数据库连接参数DB_CONFIG = {    'host': 'localhost', # 或者你的MariaDB服务器IP/域名    'user': 'your_username',    'password': 'your_password',    'database': 'your_database_name',    'charset': 'utf8mb4',    'cursorclass': pymysql.cursors.DictCursor # 可以选择返回字典形式的结果}conn = None # 初始化连接变量cursor = None # 初始化游标变量try:    # 建立数据库连接    conn = pymysql.connect(**DB_CONFIG)    # 创建游标对象,用于执行SQL命令    # 如果不设置cursorclass,默认返回元组形式的结果    cursor = conn.cursor()    # --- 执行查询操作 ---    sql_select = "SELECT id, name, age FROM users WHERE age > %s"    cursor.execute(sql_select, (25,)) # 注意这里的参数化查询,非常重要!    # 获取所有查询结果    users = cursor.fetchall()    print("查询结果:")    for user in users:        print(user)    # --- 执行插入操作 ---    # 插入数据时,也强烈建议使用参数化查询    sql_insert = "INSERT INTO users (name, age) VALUES (%s, %s)"    new_user_data = ("Alice", 30)    cursor.execute(sql_insert, new_user_data)    conn.commit() # 提交事务,让修改生效    print(f"n插入了新用户: {new_user_data[0]}, ID: {cursor.lastrowid}")    # --- 执行更新操作 ---    sql_update = "UPDATE users SET age = %s WHERE name = %s"    cursor.execute(sql_update, (31, "Alice"))    conn.commit()    print(f"n更新了 {cursor.rowcount} 条记录。")    # --- 执行删除操作 ---    sql_delete = "DELETE FROM users WHERE name = %s"    cursor.execute(sql_delete, ("Bob",))    conn.commit()    print(f"n删除了 {cursor.rowcount} 条记录。")except pymysql.Error as e:    print(f"数据库操作失败: {e}")    if conn:        conn.rollback() # 发生错误时回滚事务finally:    # 无论成功失败,确保关闭游标和连接    if cursor:        cursor.close()    if conn:        conn.close()    print("n数据库连接已关闭。")

这段代码涵盖了连接、查询、插入、更新和删除这些基本操作。特别要注意的是,我在这里使用了

cursorclass=pymysql.cursors.DictCursor

,这样查询结果会以字典的形式返回,键是列名,值是对应的数据,这在处理数据时通常比元组更方便。

Python连接MariaDB时,如何选择合适的数据库连接器?

选择Python连接MariaDB的连接器,这其实是个挺实际的问题。市面上主要的选项有

PyMySQL

mysql-connector-python

,它们都能完成任务,但在一些细节和使用体验上有所不同。

PyMySQL

是我个人在大多数非极端场景下的首选。它是一个纯Python实现的MySQL/MariaDB客户端库,这意味着它不依赖任何C语言扩展,安装起来特别省心,基本就是

pip install PyMySQL

一句话的事儿。它的API设计也比较直观,和Python的DB-API 2.0规范兼容得很好,用起来感觉很“Pythonic”。对于大多数Web应用、数据脚本或者日常的数据操作,

PyMySQL

的性能和稳定性都足够了。而且,它的社区支持很活跃,遇到问题也比较容易找到解决方案。

mysql-connector-python

,它是Oracle官方提供的MySQL连接器。它的优势在于,作为“官方出品”,理论上它对MySQL/MariaDB的最新特性和协议支持会更及时、更全面。有时候,在处理一些非常特定的数据库功能或者需要极致兼容性的场景下,它可能会表现得更好。不过,它通常会比

PyMySQL

稍微重一些,安装时可能涉及到一些编译依赖,偶尔会遇到一些环境配置上的小麻烦。但如果你在使用Oracle的其他产品,或者对“官方”这个标签有偏好,那它也是个不错的选择。

除了这两个直接的连接器,我们还会提到

SQLAlchemy

。它不是一个直接的连接器,而是一个ORM(Object-Relational Mapper)框架。

SQLAlchemy

可以作为一层抽象,运行在

PyMySQL

mysql-connector-python

之上。它的好处是让你可以用Python对象的方式来操作数据库,大大减少了直接编写SQL的工作量,也让代码更易于维护和测试。对于大型项目或者需要高度抽象的场景,

SQLAlchemy

结合任意一个连接器,都是非常强大的组合。但如果你只是写一些简单的脚本,直接使用

PyMySQL

可能更直接。

在Python操作MariaDB时,如何有效防止SQL注入攻击?

SQL注入,这个词听起来就让人头皮发麻,它是数据库安全领域一个非常经典的漏洞。简单来说,就是恶意用户通过在输入框中注入SQL代码,来改变你预期的SQL查询,从而达到非法访问、修改甚至删除数据的目的。幸好,在Python操作MariaDB时,防止SQL注入有一个非常成熟且简单有效的方法:使用参数化查询(Parameterized Queries)。

参数化查询的核心思想是,将SQL语句的结构和要传入的数据完全分开。你在编写SQL语句时,用占位符(比如

%s

)来代替实际的值,然后将这些值作为单独的参数传递给

execute()

方法。数据库驱动(比如

PyMySQL

)会负责安全地处理这些参数,它会自动对特殊字符进行转义,确保它们只被视为数据,而不是SQL代码的一部分。

我们来看个例子。假设你有一个用户登录功能,如果直接拼接字符串:

# 错误示范!极易导致SQL注入!username = input("请输入用户名: ")password = input("请输入密码: ")sql = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"cursor.execute(sql)

如果用户输入

username = 'admin' OR '1'='1' --

,那么SQL语句就会变成:

SELECT * FROM users WHERE username = 'admin' OR '1'='1' --' AND password = '...'

后面的

--

会将后续的密码验证部分注释掉,导致无需密码就能登录。这是非常危险的。

正确的做法是使用参数化查询:

# 正确示范!使用参数化查询防止SQL注入username = input("请输入用户名: ")password = input("请输入密码: ")sql = "SELECT * FROM users WHERE username = %s AND password = %s"cursor.execute(sql, (username, password)) # 将参数作为元组传递

在这种情况下,无论用户输入什么,

PyMySQL

都会将其视为普通字符串数据,并进行适当的转义。比如,如果用户输入了单引号,它会被转义成

'

,从而失去了作为SQL代码的意义。

除了参数化查询,还有一些辅助性的安全措施也值得考虑:

输入验证: 在数据进入数据库之前,对所有用户输入进行严格的验证。比如,邮箱地址必须符合邮箱格式,年龄必须是数字且在合理范围内。这虽然不能直接防止SQL注入,但可以减少恶意数据的进入。最小权限原则: 为数据库用户分配最小的必要权限。例如,一个Web应用的用户可能只需要对某些表有读写权限,而不需要删除整个数据库的权限。错误信息隐藏: 在生产环境中,不要向用户显示详细的数据库错误信息,因为这些信息可能会暴露数据库结构或敏感数据

记住,参数化查询是防止SQL注入的基石,务必在所有涉及用户输入或外部数据的SQL操作中坚持使用它。

如何在Python中处理MariaDB的事务(Transaction)?

在数据库操作中,事务(Transaction)是一个非常重要的概念,尤其是在你需要执行一系列相互关联的数据库操作时。简单来说,事务就是一组操作,它们要么全部成功提交(commit),要么全部失败回滚(rollback)。这保证了数据的一致性和完整性,避免了数据处于中间状态的混乱。想象一下银行转账,从A账户扣钱和B账户加钱必须同时成功或同时失败,不能只成功一个。

MariaDB(以及MySQL)默认情况下,每个独立的SQL语句都是一个隐式的事务,会自动提交。但在Python中,当我们通过

PyMySQL

这样的连接器操作时,通常会关闭自动提交(或者默认就是关闭的),这样我们就可以手动控制事务的边界。

处理事务的基本流程是:

开始事务: 通常通过设置连接的

autocommit

属性为

False

来明确控制。执行一系列SQL操作: 这些操作都在同一个事务中。提交事务: 如果所有操作都成功,调用

connection.commit()

将所有修改永久保存到数据库。回滚事务: 如果在任何一个操作中发生错误,调用

connection.rollback()

撤销事务中的所有修改,使数据库回到事务开始前的状态。

我们来看一个模拟银行转账的例子,它很好地展示了事务的用法:

import pymysqlDB_CONFIG = {    'host': 'localhost',    'user': 'your_username',    'password': 'your_password',    'database': 'your_database_name',    'charset': 'utf8mb4',    'cursorclass': pymysql.cursors.DictCursor}conn = Nonecursor = Nonetry:    conn = pymysql.connect(**DB_CONFIG)    # 禁用自动提交,手动控制事务    conn.autocommit = False     cursor = conn.cursor()    from_account_id = 101    to_account_id = 102    amount_to_transfer = 50.0    print(f"尝试从账户 {from_account_id} 转账 {amount_to_transfer} 到账户 {to_account_id}...")    # 1. 检查转出账户余额    cursor.execute("SELECT balance FROM accounts WHERE id = %s FOR UPDATE", (from_account_id,))    from_balance = cursor.fetchone()    if not from_balance or from_balance['balance'] < amount_to_transfer:        raise ValueError("转出账户余额不足或账户不存在!")    # 2. 从转出账户扣款    sql_deduct = "UPDATE accounts SET balance = balance - %s WHERE id = %s"    cursor.execute(sql_deduct, (amount_to_transfer, from_account_id))    print(f"已从账户 {from_account_id} 扣除 {amount_to_transfer}。")    # 3. 向转入账户加款    sql_add = "UPDATE accounts SET balance = balance + %s WHERE id = %s"    cursor.execute(sql_add, (amount_to_transfer, to_account_id))    print(f"已向账户 {to_account_id} 增加 {amount_to_transfer}。")    # 如果所有操作都成功,提交事务    conn.commit()    print("n转账成功!所有操作已提交。")except pymysql.Error as e:    print(f"n数据库操作失败: {e}")    if conn:        conn.rollback() # 发生任何错误,回滚所有操作        print("事务已回滚。")except ValueError as ve:    print(f"n业务逻辑错误: {ve}")    if conn:        conn.rollback() # 业务逻辑错误也回滚        print("事务已回滚。")finally:    if cursor:        cursor.close()    if conn:        conn.close()    print("数据库连接已关闭。")

在这个例子中,

FOR UPDATE

子句在查询余额时锁定行,防止其他事务同时修改这些账户的余额,这在并发场景下非常重要。如果在扣款或加款的任何一步发生错误(比如网络中断、数据库死锁),

except

块会被触发,

conn.rollback()

会确保之前的所有修改都被撤销,账户余额不会出现不一致的情况。

使用事务时,有几个小点需要注意:

不要忘记

commit()

这是新手最常犯的错误。如果你执行了修改操作但没有

commit()

,那么这些修改只在当前连接中可见,一旦连接关闭,修改就会丢失。事务的粒度: 事务不宜过大,长时间的事务会占用数据库资源,影响并发性能。尽量让事务只包含必要的操作,并在完成任务后尽快提交或回滚。错误处理: 确保在代码中捕获可能发生的数据库错误,并在错误发生时进行回滚。这通常通过

try...except...finally

结构来实现。

理解并熟练运用事务,是编写健壮、可靠的数据库应用的关键。

以上就是Python怎样操作MariaDB数据库?mariadb连接器的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1366700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 06:48:02
下一篇 2025年12月14日 06:48:13

相关推荐

  • Python如何制作地理信息地图?folium可视化技巧

    使用folium制作地理信息地图的核心步骤为:1. 创建folium.map对象并设置中心坐标和缩放级别;2. 添加标记点、区域或路线等地理元素,如folium.marker、folium.geojson;3. 针对大量点数据使用folium.plugins.markercluster实现聚合优化性…

    好文分享 2025年12月14日
    000
  • 如何用Python源码处理短视频剪辑任务 Python源码支持批量视频处理

    python用moviepy和opencv可高效批量剪辑短视频,实现裁剪、拼接、加水印、格式统一等自动化操作;2. 性能优化靠多进程并行处理、合理设置ffmpeg编码参数(如preset和threads)、避免内存溢出;3. 常见挑战包括ffmpeg兼容性、音视频不同步、资源耗尽,解决方法为dock…

    2025年12月14日 好文分享
    000
  • Python如何创建虚拟环境?venv模块使用技巧

    创建python虚拟环境是为了隔离项目依赖、避免版本冲突,推荐使用python自带的venv模块。1. 创建虚拟环境:在项目目录下运行 python3 -m venv .venv,生成包含独立python和pip的 .venv 文件夹。2. 激活虚拟环境:linux/macos运行 source .…

    2025年12月14日
    000
  • Python怎样构建自动化爬虫系统?Scrapy-Redis

    scrapy-redis通过重写scrapy的调度器和去重过滤器,利用redis作为分布式队列和去重中心,实现多节点共享任务队列和指纹库,从而支持横向扩展与容错恢复;1. 调度器将请求存入redis list,实现分布式任务分配;2. 去重过滤器使用redis set存储请求指纹,确保url不重复抓…

    2025年12月14日
    000
  • Python函数怎样用参数注解生成函数文档 Python函数注解文档化的简单方法​

    使用sphinx自动生成带有参数注解的函数文档:首先安装sphinx和sphinx.ext.napoleon,然后在conf.py中启用autodoc和napoleon扩展,确保函数包含docstrings和类型注解,接着在.rst文件中使用automodule指令指定模块并启用members选项,…

    2025年12月14日
    000
  • 选择 Socket recv 缓冲区大小的考量

    在 Socket 编程中,尤其是在网络通信或进程间通信(IPC)中,recv() 函数用于从 Socket 接收数据。recv() 函数的第一个参数,即缓冲区大小,决定了每次调用最多可以接收的字节数。虽然从逻辑上讲,无论缓冲区大小如何,程序的最终行为可能保持不变,但缓冲区大小的选择会对程序的性能和资…

    2025年12月14日
    000
  • 选择 Socket 接收缓冲区大小的考量

    本文探讨了在使用 Socket 进行数据接收时,recv() 函数的缓冲区大小参数选择问题。重点分析了不同缓冲区大小对性能和资源消耗的影响,并结合实际应用场景,为开发者提供选择合适的缓冲区大小的建议,旨在帮助开发者在性能和资源之间做出平衡,提升网络应用的效率。 在使用 Socket 编程时,recv…

    2025年12月14日
    000
  • 输出格式要求:使用 Python 检查图像是否损坏:实用指南

    本文旨在提供一个清晰、简洁的指南,教你如何使用 Python 和 PIL 库来检测图像文件是否损坏。通过一个实际案例,我们将深入探讨常见的错误,并提供正确的代码实现,帮助你构建一个可靠的图像验证工具。 在处理图像数据时,确保图像文件的完整性至关重要。损坏的图像可能导致程序崩溃或产生错误的结果。pyt…

    2025年12月14日
    000
  • Python图像校验:使用PIL库检测图像是否损坏

    本文旨在指导开发者使用Python的PIL(Pillow)库,编写高效的图像校验程序,以检测图像文件是否损坏。通过实例代码演示了如何打开图像并利用try-except块捕获异常,从而判断图像的完整性。同时,强调了变量命名规范和正确的函数调用方式,避免常见错误。 图像校验:使用PIL库检测图像是否损坏…

    2025年12月14日
    000
  • 如何使用 try/except 处理图像损坏问题

    本文旨在帮助开发者使用 try/except 语句检测图像文件是否损坏。我们将通过一个实际案例,分析常见错误,并提供正确的代码示例,确保程序能够准确识别并处理损坏的图像文件。 在使用 Python 处理图像时,经常需要检测图像文件是否损坏。一种常见的方法是使用 PIL (Pillow) 库的 Ima…

    2025年12月14日
    000
  • 基于分组和条件添加新列:Pandas教程

    本文详细介绍了如何使用 Pandas 在 DataFrame 中基于分组和条件添加新列。通过 groupby()、apply()、sort_values()、shift() 和 cumsum() 等函数的组合使用,可以实现复杂的数据转换和列生成。本文提供清晰的代码示例和详细的步骤解释,帮助读者理解并…

    2025年12月14日
    000
  • SymPy表达式在终端与GUI中的美观显示方法

    本教程旨在解决在Python环境中,尤其是在Pydroid3终端和Tkinter GUI中,如何美观地显示SymPy数学表达式的问题。文章将深入探讨SymPy库提供的pprint()和pretty()函数,它们能够生成易于阅读的文本格式表达式。通过具体的代码示例,教程将展示如何在不同场景下利用这些函…

    2025年12月14日
    000
  • 在Pydroid3及GUI中美观显示SymPy表达式的实用指南

    本教程详细讲解如何在Pydroid3终端和桌面GUI(如Tkinter)中实现SymPy表达式的美观打印。文章阐述了sympy.pprint()和sympy.pretty()函数的工作原理,它们能将复杂的数学表达式渲染为易于在各类环境中显示的字符艺术字符串。通过具体的代码示例,您将掌握如何在Pydr…

    2025年12月14日
    000
  • SymPy表达式在Pydroid3终端与GUI中的美观显示策略

    本文探讨了在Pydroid3终端以及GUI环境中美观显示SymPy数学表达式的方法。针对init_printing在特定环境下可能失效的问题,详细介绍了如何利用sympy.pprint和sympy.pretty函数生成字符画形式的表达式,并探讨了在Tkinter等GUI界面中显示这些表达式的策略,以…

    2025年12月14日
    000
  • SymPy表达式在Pydroid3终端与GUI中的美观显示方法

    本文旨在解决在Pydroid3等移动开发环境中,SymPy表达式无法正常美观显示的问题。传统init_printing方法可能失效,但可通过sympy.pprint()或sympy.pretty()函数获取格式化字符串,从而在终端中实现美观输出。对于GUI显示,将探讨将这些字符串集成到Tkinter…

    2025年12月14日
    000
  • 在Pydroid3中美观打印SymPy表达式及GUI显示方案

    本教程旨在解决在Pydroid3环境中美观打印SymPy表达式的问题,特别是当init_printing无效时。文章将详细介绍如何利用SymPy内置的pprint()和pretty()函数在终端输出格式化的数学表达式。同时,针对在Tkinter或其他GUI框架中显示复杂数学表达式的需求,本教程将探讨…

    2025年12月14日
    000
  • Django批量更新数据未生效问题排查与解决

    在django开发中,我们经常需要批量更新数据库中的数据。update()方法是django orm提供的一种高效的批量更新方式。然而,有时我们可能会遇到使用update()方法更新数据后,数据库中的数据并没有如预期那样发生改变的情况。本文将深入探讨这个问题,并提供相应的解决方案。 update()…

    2025年12月14日
    000
  • Django批量更新数据未生效问题排查与解决方案

    Django框架中使用update()方法批量更新数据库时,可能会遇到数据未生效的问题。这是因为update()方法直接转换为SQL语句执行,属于批量操作,它不会触发模型的save()方法,也不会发出pre_save或post_save信号,更不会考虑auto_now字段的设置。因此,如果你的模型中…

    2025年12月14日
    000
  • 从字符串中调用变量:Pandas DataFrame 中的动态计算

    本文旨在解决 Pandas DataFrame 中,当某一列的值为包含变量的字符串时,如何进行动态计算的问题。通过字符串拆分和类型转换,结合 Pandas 的数据操作,提供了一种安全高效的方法,避免使用 eval() 函数,实现从字符串中提取变量并进行计算,最终得到所需的结果。 在数据处理过程中,我…

    2025年12月14日
    000
  • 从字符串中调用变量并进行计算的实用方法

    本文针对Pandas DataFrame中,当某一列的字符串值包含变量名和运算符时,如何提取变量并进行计算的问题,提供了一种安全且高效的解决方案。通过字符串分割和类型转换,避免了使用eval()带来的安全风险,并展示了如何利用Pandas的强大功能实现批量计算。 在数据处理过程中,我们经常会遇到需要…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信