原文围绕Python连接MySQL和PostgreSQL展开,选用mysql-connector-python与psycopg2两个库,覆盖安装、连接配置、查询、增删改、事务和备份恢复。原文代码结构清晰,但数据交互、事务与备份恢复部分存在明显的库兼容问题:MySQL/PostgreSQL的参数化查询并不是问号占位符,备份恢复和实战案例又混入了SQLite的iterdump与sqlite3。下面按原文事实重组,并标出容易照搬出错的地方。
一、依赖安装与连接配置
原文给出的安装命令如下:- pip install mysql-connector-python
- pip install psycopg2
复制代码 MySQL连接使用配置字典传入user、password、host、database四个参数,再通过mysql.connector.connect(**config)创建连接。查询时先conn.cursor()创建游标,再execute执行SELECT,最后直接遍历游标打印结果:- import mysql.connector
- config = {
- 'user': 'root',
- 'password': 'password',
- 'host': 'localhost',
- 'database': 'test_db'
- }
- conn = mysql.connector.connect(**config)
- cursor = conn.cursor()
- cursor.execute('SELECT * FROM test_table')
- for row in cursor:
- print(row)
复制代码 PostgreSQL连接使用psycopg2.connect(**config),配置键同样是user、password、host、database,查询流程与MySQL示例基本一致:- import psycopg2
- config = {
- 'user': 'postgres',
- 'password': 'password',
- 'host': 'localhost',
- 'database': 'test_db'
- }
- conn = psycopg2.connect(**config)
- cursor = conn.cursor()
- cursor.execute('SELECT * FROM test_table')
- for row in cursor:
- print(row)
复制代码 从调用方式看,两个库都遵循“连接对象创建游标、游标执行SQL、遍历游标读取结果”的模式,差异主要在驱动包和参数占位符。
二、增删改与参数占位符误区
原文在数据插入、更新、删除部分统一写成问号占位符,例如INSERT INTO test_table (column1, column2) VALUES (?, ?)。这种写法在SQLite中常见,但mysql-connector-python和psycopg2的参数化查询通常使用%s,不是?。如果直接照搬原文代码,容易出现SQL语法错误或参数绑定异常。按原文逻辑修正占位符后,插入、更新、删除可写成:- cursor = conn.cursor()
- cursor.execute('INSERT INTO test_table (column1, column2) VALUES (%s, %s)', (value1, value2))
- conn.commit()
- cursor.execute('UPDATE test_table SET column1 = %s WHERE column2 = %s', (new_value1, old_value2))
- conn.commit()
- cursor.execute('DELETE FROM test_table WHERE column1 = %s', (value1,))
- conn.commit()
复制代码 这里commit的作用是提交事务。插入、更新、删除之后如果不提交,连接关闭或回滚时数据可能不会落库。原文在每次操作后都调用conn.commit(),这一点是正确的。
三、事务处理代码的复用问题
原文把事务处理拆成MySQL和PostgreSQL两小节,但给出的代码逻辑相同:先conn.begin()表示开始事务,再连续执行插入、更新、删除,最后conn.commit()提交。示例中的SQL同样使用了问号占位符:- conn.begin()
- cursor.execute('INSERT INTO test_table (column1, column2) VALUES (%s, %s)', (value1, value2))
- cursor.execute('UPDATE test_table SET column1 = %s WHERE column2 = %s', (new_value1, old_value2))
- cursor.execute('DELETE FROM test_table WHERE column1 = %s', (value1,))
- conn.commit()
复制代码 这段代码的关键点是多条SQL要么一起提交,要么在异常时回滚。实际使用时还要确认所用驱动是否提供begin方法,以及异常处理中是否调用rollback。原文只展示了begin与commit的主流程,没有展开异常分支,照搬时不能把占位符和驱动API混用。
四、备份恢复部分实际是SQLite写法
原文数据库备份使用conn.iterdump(),恢复使用sqlite3.connect创建新连接,并逐行执行备份SQL:- with open('backup.sql', 'w') as f:
- for line in conn.iterdump():
- f.write(line)
- new_conn = sqlite3.connect('example.db')
- with open('backup.sql', 'r') as f:
- for line in f:
- 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展开:- import sqlite3
- conn = sqlite3.connect('user_system.db')
- conn.execute('''
- CREATE TABLE IF NOT EXISTS users (
- id INTEGER PRIMARY KEY,
- name TEXT NOT NULL,
- email TEXT UNIQUE NOT NULL
- )
- ''')
- conn.execute('INSERT INTO users (name, email) VALUES (?, ?)', ('Alice', 'alice@example.com'))
- conn.execute('INSERT INTO users (name, email) VALUES (?, ?)', ('Bob', 'bob@example.com'))
- cursor = conn.execute('SELECT * FROM users WHERE email = ?', ('alice@example.com',))
- for row in cursor:
- print(row)
- conn.execute('UPDATE users SET email = ? WHERE id = ?', ('alice_new@example.com', 1))
- conn.execute('DELETE FROM users WHERE id = ?', (2,))
- conn.execute('BEGIN TRANSACTION')
- conn.executemany('INSERT INTO users (name, email) VALUES (?, ?)', [('Charlie', 'charlie@example.com'), ('David', 'david@example.com')])
- 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连接对象上。 |