查看: 176|回复: 3

Python连接MySQL/PostgreSQL占位符与备份恢复误区

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
原文围绕Python连接MySQL和PostgreSQL展开,选用mysql-connector-python与psycopg2两个库,覆盖安装、连接配置、查询、增删改、事务和备份恢复。原文代码结构清晰,但数据交互、事务与备份恢复部分存在明显的库兼容问题:MySQL/PostgreSQL的参数化查询并不是问号占位符,备份恢复和实战案例又混入了SQLite的iterdump与sqlite3。下面按原文事实重组,并标出容易照搬出错的地方。

一、依赖安装与连接配置
原文给出的安装命令如下:
  1. pip install mysql-connector-python
  2. pip install psycopg2
复制代码
MySQL连接使用配置字典传入user、password、host、database四个参数,再通过mysql.connector.connect(**config)创建连接。查询时先conn.cursor()创建游标,再execute执行SELECT,最后直接遍历游标打印结果:
  1. import mysql.connector
  2. config = {
  3.     'user': 'root',
  4.     'password': 'password',
  5.     'host': 'localhost',
  6.     'database': 'test_db'
  7. }
  8. conn = mysql.connector.connect(**config)
  9. cursor = conn.cursor()
  10. cursor.execute('SELECT * FROM test_table')
  11. for row in cursor:
  12.     print(row)
复制代码
PostgreSQL连接使用psycopg2.connect(**config),配置键同样是user、password、host、database,查询流程与MySQL示例基本一致:
  1. import psycopg2
  2. config = {
  3.     'user': 'postgres',
  4.     'password': 'password',
  5.     'host': 'localhost',
  6.     'database': 'test_db'
  7. }
  8. conn = psycopg2.connect(**config)
  9. cursor = conn.cursor()
  10. cursor.execute('SELECT * FROM test_table')
  11. for row in cursor:
  12.     print(row)
复制代码
从调用方式看,两个库都遵循“连接对象创建游标、游标执行SQL、遍历游标读取结果”的模式,差异主要在驱动包和参数占位符。

二、增删改与参数占位符误区
原文在数据插入、更新、删除部分统一写成问号占位符,例如INSERT INTO test_table (column1, column2) VALUES (?, ?)。这种写法在SQLite中常见,但mysql-connector-python和psycopg2的参数化查询通常使用%s,不是?。如果直接照搬原文代码,容易出现SQL语法错误或参数绑定异常。按原文逻辑修正占位符后,插入、更新、删除可写成:
  1. cursor = conn.cursor()
  2. cursor.execute('INSERT INTO test_table (column1, column2) VALUES (%s, %s)', (value1, value2))
  3. conn.commit()
  4. cursor.execute('UPDATE test_table SET column1 = %s WHERE column2 = %s', (new_value1, old_value2))
  5. conn.commit()
  6. cursor.execute('DELETE FROM test_table WHERE column1 = %s', (value1,))
  7. conn.commit()
复制代码
这里commit的作用是提交事务。插入、更新、删除之后如果不提交,连接关闭或回滚时数据可能不会落库。原文在每次操作后都调用conn.commit(),这一点是正确的。

三、事务处理代码的复用问题
原文把事务处理拆成MySQL和PostgreSQL两小节,但给出的代码逻辑相同:先conn.begin()表示开始事务,再连续执行插入、更新、删除,最后conn.commit()提交。示例中的SQL同样使用了问号占位符:
  1. conn.begin()
  2. cursor.execute('INSERT INTO test_table (column1, column2) VALUES (%s, %s)', (value1, value2))
  3. cursor.execute('UPDATE test_table SET column1 = %s WHERE column2 = %s', (new_value1, old_value2))
  4. cursor.execute('DELETE FROM test_table WHERE column1 = %s', (value1,))
  5. conn.commit()
复制代码
这段代码的关键点是多条SQL要么一起提交,要么在异常时回滚。实际使用时还要确认所用驱动是否提供begin方法,以及异常处理中是否调用rollback。原文只展示了begin与commit的主流程,没有展开异常分支,照搬时不能把占位符和驱动API混用。

四、备份恢复部分实际是SQLite写法
原文数据库备份使用conn.iterdump(),恢复使用sqlite3.connect创建新连接,并逐行执行备份SQL:
  1. with open('backup.sql', 'w') as f:
  2.     for line in conn.iterdump():
  3.         f.write(line)
  4. new_conn = sqlite3.connect('example.db')
  5. with open('backup.sql', 'r') as f:
  6.     for line in f:
  7.         new_conn.execute(line)
复制代码
这段代码的事实是:iterdump是SQLite连接对象的方法,sqlite3也是SQLite驱动,并不是MySQL或PostgreSQL的连接库。若conn来自mysql.connector或psycopg2,直接调用iterdump会因方法不存在而报错;恢复阶段创建的也是SQLite文件,不是MySQL/PostgreSQL数据库。原文没有给出MySQL/PostgreSQL对应的备份命令,因此这部分不能当作跨数据库备份恢复方案直接使用。

五、实战案例同样是SQLite用户管理
原文第8节用户管理案例实际导入sqlite3,创建user_system.db,并建立users表。建表、注册、登录、更新、删除和事务代码都围绕SQLite展开:
  1. import sqlite3
  2. conn = sqlite3.connect('user_system.db')
  3. conn.execute('''
  4. CREATE TABLE IF NOT EXISTS users (
  5.     id INTEGER PRIMARY KEY,
  6.     name TEXT NOT NULL,
  7.     email TEXT UNIQUE NOT NULL
  8. )
  9. ''')
  10. conn.execute('INSERT INTO users (name, email) VALUES (?, ?)', ('Alice', 'alice@example.com'))
  11. conn.execute('INSERT INTO users (name, email) VALUES (?, ?)', ('Bob', 'bob@example.com'))
  12. cursor = conn.execute('SELECT * FROM users WHERE email = ?', ('alice@example.com',))
  13. for row in cursor:
  14.     print(row)
  15. conn.execute('UPDATE users SET email = ? WHERE id = ?', ('alice_new@example.com', 1))
  16. conn.execute('DELETE FROM users WHERE id = ?', (2,))
  17. conn.execute('BEGIN TRANSACTION')
  18. conn.executemany('INSERT INTO users (name, email) VALUES (?, ?)', [('Charlie', 'charlie@example.com'), ('David', 'david@example.com')])
  19. conn.commit()
复制代码
这段代码作为SQLite示例是完整的,但与文章标题中的MySQL和PostgreSQL并不一致。若要把同一套用户管理逻辑迁移到MySQL或PostgreSQL,至少需要替换连接库和占位符:mysql-connector-python与psycopg2使用%s,SQLite使用?;备份恢复也不能沿用iterdump。

六、结论
原文的价值在于展示了Python数据库操作的基本骨架:安装驱动、配置连接、创建游标、执行查询、提交事务。需要重点注意的是,MySQL/PostgreSQL与SQLite在占位符和备份恢复API上并不通用。改写或复用原文代码时,应把数据交互部分的问号占位符替换为%s,把备份恢复和实战案例识别为SQLite示例,避免把sqlite3的iterdump直接套到MySQL/PostgreSQL连接对象上。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python连接MySQL/PostgreSQL占位符与备份恢复误区

这帖整理得很实在,尤其是占位符那一节。我以前拿SQLite的写法直接套到psycopg2上,就是被问号占位符坑了一下午,报错还不太直观,后来才知道MySQL和PostgreSQL这两个驱动都得用%s,连只有一个参数时也得写成元组形式,少了逗号照样出错。事务部分你提到begin和rollback这点也很关键,实际项目里光有commit不够,异常分支里不rollback很容易把连接卡在事务里,后面再操作就各种奇怪状态。备份恢复那块确实是最容易照搬翻车的地方,iterdump只有sqlite3的连接对象才有,换成mysql.connector或者psycopg2直接调用肯定是报方法不存在,恢复时又用sqlite3.connect建了个本地文件,表面能跑通,其实跟MySQL/PostgreSQL一点关系没有。如果后面能补上这两类库各自的实际备份方式,或者至少明确标一句“以下仅适用于SQLite”,对新手会更友好。另外帖子好像在第8节用户管理案例那里被截断了,期待后续把那个SQLite实战的坑也讲完。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python连接MySQL/PostgreSQL占位符与备份恢复误区

这篇整理挺实用的,把问号占位符和 iterdump 这两个最容易照搬出错的地方都点出来了。参数化查询统一用 %s、增删改后记得 commit、事务要考虑异常回滚,这些确实是实际写脚本时很容易踩的坑。备份恢复部分也提醒得很到位,SQLite 的 iterdump 和 sqlite3 不能直接套到 MySQL 或 PostgreSQL 上,否则方法不存在或者恢复到了错误的数据库。整体结构清楚,适合当避坑笔记。要是后面能再补上 MySQL 和 PostgreSQL 各自常见的备份恢复写法,以及 psycopg2 安装时可能遇到的编译依赖问题,新手照着做会更稳。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python连接MySQL/PostgreSQL占位符与备份恢复误区

楼主这篇梳理得很到位,占位符和备份恢复这两处确实是最容易照搬踩坑的地方。我补充几点实际使用中容易忽略的细节。 第一,占位符统一用 %s 这点没问题,但要注意 psycopg2 里不管字段是整型、字符串还是日期,一律写 %s,不要自己加引号,也不要用 %d,否则反而会绑定失败。另外如果 SQL 里本身有百分号(比如 LIKE 模式),要写成 %%。 第二,事务部分原文用 conn.begin(),但实际上 psycopg2 默认就是非自动提交,执行完第一条 SQL 事务就已经开始了,显式 begin 不是必须的;mysql-connector-python 更推荐用 conn.start_transaction() 或者直接依赖 autocommit=False。关键是异常分支一定要补 try/except 加 conn.rollback(),不然出错了连接可能还挂着未提交事务。 第三,备份恢复那段确实是 SQLite 专属,MySQL 对应的是 mysqldump,PostgreSQL 对应 pg_dump / pg_restore,用 Python 调的话一般走 subprocess,而不是在连接对象上找方法。恢复时还要注意先建库、字符集和权限,不然导进去容易乱码或失败。 第四,查询遍历游标那块,数据量大时最好用 fetchmany 分批取,别一次性全读进内存;用完记得 curs
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-11-12 04:52 , Processed in 0.020731 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部