一、SQLite 3 增删改查
在Python中使用SQLite 3进行数据库操作是一种常见的实践,特别是对于小型应用程序或原型开发。以下是使用Python标准库中的`sqlite3`模块进行增删改查(CRUD)操作的基本示例。
1. 连接数据库
首先,需要连接到SQLite数据库。如果数据库文件不存在,`sqlite3.connect()`将会创建一个新的数据库文件。
python
import sqlite3
# 连接到SQLite数据库
# 如果文件不存在,会自动在当前目录创建:
conn = sqlite3.connect('example.db')
# 创建一个Cursor对象,并通过它来执行SQL命令
c = conn.cursor()
2. 创建表
使用`cursor`对象执行SQL命令来创建表。
python
# 插入数据
c.execute("INSERT INTO users (name, age) VALUES ('Alice', 21)")
# 提交事务
conn.commit()
3. 插入数据
使用`execute()`方法插入数据。
python
# 插入数据
c.execute("INSERT INTO users (name, age) VALUES ('Alice', 21)")
# 提交事务
conn.commit()
4. 查询数据
使用`execute()`方法查询数据,并使用`fetchall()`或`fetchone()`获取结果。
python
# 查询数据
c.execute('SELECT * FROM users')
# 获取所有用户
users = c.fetchall()
for user in users:
print(user)
# 提交事务
conn.commit()
5. 更新数据
使用`execute()`方法更新数据。
python
# 更新数据
c.execute("UPDATE users SET age = 22 WHERE name = 'Alice'")
# 提交事务
conn.commit()
6. 删除数据
使用`execute()`方法删除数据。
python
# 删除数据
c.execute("DELETE FROM users WHERE name = 'Alice'")
# 提交事务
conn.commit()
7. 关闭连接
完成所有数据库操作后,应该关闭cursor和连接。
python
# 关闭cursor
c.close()
# 关闭连接
conn.close()
这些是使用Python进行SQLite 3数据库操作的基本步骤。在实际应用中,可能需要处理异常和更复杂的事务管理,但上述示例提供了一个良好的起点。
二、异常处理和事务管理
在Python中使用SQLite 3时,异常处理和事务管理是确保数据库操作稳定性和数据一致性的重要方面。以下是如何在Python中使用`sqlite3`模块进行异常处理和事务管理的示例。
异常处理
当执行数据库操作时,可能会遇到各种错误,如语法错误、约束违规等。为了妥善处理这些错误,可以使用`try`和`except`语句捕获异常。
python
import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
try:
# 尝试执行一个SQL语句
c.execute("SELEC * FROM users") # 故意写错的SQL语句
except sqlite3.DatabaseError as e:
print(f"数据库错误: {e}")
except sqlite3.IntegrityError as e:
print(f"完整性错误: {e}")
except Exception as e:
print(f"其他错误: {e}")
finally:
# 无论是否发生异常,都尝试提交事务
conn.commit()
# 关闭cursor和连接
c.close()
conn.close()
事务管理
SQLite支持事务,事务可以确保数据库操作的原子性。在`sqlite3`模块中,事务管理可以通过显式地开始和提交事务来实现。
python
import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
try:
# 开始一个事务
conn.execute('BEGIN TRANSACTION;')
# 执行一系列数据库操作
c.execute("INSERT INTO users (name, age) VALUES ('Bob', 20)")
c.execute("INSERT INTO users (name, age) VALUES ('Charlie', 25)")
# 提交事务
conn.commit()
print("事务提交成功")
except sqlite3.Error as e:
print(f"发生错误: {e}")
# 如果发生错误,回滚事务
conn.rollback()
print("事务已回滚")
finally:
# 关闭cursor和连接
c.close()
conn.close()
在这个示例中,我们使用`BEGIN TRANSACTION;`显式地开始了一个事务。如果在执行SQL语句时发生错误,我们捕获异常并调用`conn.rollback()`来撤销事务中的所有操作。如果一切顺利,则调用`conn.commit()`来提交事务。
自动事务管理
`sqlite3`模块还提供了`commit`和`rollback`的自动管理。如果在执行操作后没有调用`commit()`,那么在下一次操作开始时,上一个事务会自动提交。如果在执行操作时发生异常,事务会自动回滚。
python
import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
try:
# 执行一系列数据库操作
c.execute("INSERT INTO users (name, age) VALUES ('Dave', 30)")
c.execute("INSERT INTO users (name, age) VALUES ('Eve', 22)")
# 由于没有显式调用commit,如果在下一次操作前发生异常,会自动回滚
except sqlite3.Error as e:
print(f"发生错误: {e}")
# 由于异常,事务会自动回滚
finally:
# 关闭cursor和连接
c.close()
conn.close()
在实际应用中,根据需求选择合适的事务管理策略是非常重要的。对于复杂的数据库操作,显式管理事务可以提供更好的控制。
三、关联查询(JOIN)和分页查询
在SQLite中,关联查询(JOIN)和分页查询是两种常见的操作,它们可以帮助你从数据库中检索和组织数据。以下是如何在Python中使用`sqlite3`模块来执行这些操作的示例
关联查询(JOIN)
假设我们有两个表:`users`和`orders`,我们想要获取所有用户的详细信息以及他们对应的订单。
python
import sqlite3
# 连接到数据库
conn = sqlite3.connect('example.db')
c = conn.cursor()
# 创建示例表
c.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT
)
''')
c.execute('''
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
product TEXT,
FOREIGN KEY (user_id) REFERENCES users (id)
)
''')
conn.commit()
# 插入示例数据
c.execute("INSERT INTO users (name) VALUES ('Alice')")
c.execute("INSERT INTO users (name) VALUES ('Bob')")
c.execute("INSERT INTO orders (user_id, product) VALUES (1, 'Book')")
c.execute("INSERT INTO orders (user_id, product) VALUES (1, 'Pen')")
c.execute("INSERT INTO orders (user_id, product) VALUES (2, 'Laptop')")
conn.commit()
# 执行关联查询
c.execute('''
SELECT users.name, orders.product
FROM users
JOIN orders ON users.id = orders.user_id
''')
# 获取查询结果
rows = c.fetchall()
for row in rows:
print(row)
# 关闭cursor和连接
c.close()
conn.close()
分页查询
分页查询通常用于在Web应用程序中显示数据,以避免一次性加载过多数据。以下是一个分页查询的示例。
python
import sqlite3
# 连接到数据库
conn = sqlite3.connect('example.db')
c = conn.cursor()
# 假设我们已经有了users表和一些数据
# 分页查询,每页显示2条数据,获取第2页的数据
page_size = 2
page_number = 2
offset = (page_number - 1) * page_size
c.execute('''
SELECT * FROM users
LIMIT ? OFFSET ?
''', (page_size, offset))
# 获取查询结果
rows = c.fetchall()
for row in rows:
print(row)
# 关闭cursor和连接
c.close()
conn.close()
在这个分页查询的例子中,我们使用了`LIMIT`和`OFFSET`子句。`LIMIT`定义了每页显示的记录数,而`OFFSET`定义了开始选择记录之前要跳过的记录数。`OFFSET`的值通常是`(page_number - 1) * page_size`。请注意,分页查询可能会因为索引和数据量的不同而影响性能,特别是在大数据集上。在设计数据库和查询时,应该考虑到这一点,并适当地使用索引来优化查询性能。
四、MVC(Model-View-Controller)设计模式,
在软件开发中,MVC(Model-View-Controller)是一种常用的设计模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。在Python中使用SQLite 3时,也可以采用MVC模式来组织代码,使得数据库操作(Model)、用户界面(View)和业务逻辑(Controller)分离,提高代码的可维护性和可扩展性。
以下是一个简单的示例,展示如何在Python中使用SQLite 3实现MVC模式:
1. Model(模型)
模型负责处理数据和业务逻辑。在SQLite 3的上下文中,模型可能会包含数据库连接和CRUD操作。
python
import sqlite3
class UserModel:
def __init__(self, db_path):
self.conn = sqlite3.connect(db_path)
self.cursor = self.conn.cursor()
self.cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
age INTEGER NOT NULL
)
''')
self.conn.commit()
def add_user(self, name, age):
self.cursor.execute('INSERT INTO users (name, age) VALUES (?, ?)', (name, age))
self.conn.commit()
def get_users(self):
self.cursor.execute('SELECT * FROM users')
return self.cursor.fetchall()
def delete_user(self, user_id):
self.cursor.execute('DELETE FROM users WHERE id = ?', (user_id,))
self.conn.commit()
def __del__(self):
self.conn.close()
2. View(视图)
视图负责显示数据(即用户界面)。在命令行应用程序中,视图可能是简单的打印语句。
python
def show_menu():
print("1. Add User")
print("2. Show Users")
print("3. Delete User")
print("4. Exit")
def show_users(users):
for user in users:
print(f"ID: {user[0]}, Name: {user[1]}, Age: {user[2]}")
def get_user_input():
return input("Enter your choice: ")
3. Controller(控制器)
控制器负责接收用户输入,调用模型和视图之间的交互。
python
def main():
user_model = UserModel('example.db')
while True:
show_menu()
choice = get_user_input()
if choice == '1':
name = input("Enter name: ")
age = input("Enter age: ")
user_model.add_user(name, age)
elif choice == '2':
users = user_model.get_users()
show_users(users)
elif choice == '3':
user_id = int(input("Enter user ID to delete: "))
user_model.delete_user(user_id)
elif choice == '4':
break
else:
print("Invalid choice. Please try again.")
if __name__ == '__main__':
main()
在这个示例中,`UserModel`是模型,它处理所有与数据库相关的操作。视图由`show_menu`、`show_users`和`get_user_input`函数组成,它们负责与用户交互。控制器是`main`函数,它控制应用程序的流程,根据用户的选择调用模型和视图。
请注意,这只是一个简单的示例,实际的MVC实现可能会更复杂,并且可能涉及更多的组件和层次。此外,对于Web应用程序,你可能会使用像Flask或Django这样的框架,它们提供了内置的MVC结构。
五、Web中的MVC模式
在Web开发中,使用Flask框架和SQLite 3数据库可以实现MVC模式。Flask是一个轻量级的Web应用框架,它可以让你快速地构建Web应用。以下是如何在Flask中使用SQLite 3实现MVC模式的示例。
1. 初始化Flask应用
首先,创建一个Flask应用,并设置好SQLite数据库。
python
from flask import Flask, request, render_template
import sqlite3
app = Flask(__name__)
# 数据库路径
DATABASE = 'example.db'
def get_db():
conn = sqlite3.connect(DATABASE)
conn.row_factory = sqlite3.Row
return conn
@app.before_first_request
def create_tables():
with app.app_context():
db = get_db()
db.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
age INTEGER NOT NULL
)
''')
db.commit()
db.close()
2. Model(模型)
在MVC模式中,模型负责处理数据和业务逻辑。在Flask应用中,你可以创建一个模型类来封装数据库操作。
python
class UserModel:
def __init__(self, db):
self.db = db
def add_user(self, name, age):
self.db.execute('INSERT INTO users (name, age) VALUES (?, ?)', (name, age))
self.db.commit()
def get_users(self):
return self.db.execute('SELECT * FROM users').fetchall()
def delete_user(self, user_id):
self.db.execute('DELETE FROM users WHERE id = ?', (user_id,))
self.db.commit()
3. View(视图)
在Flask中,视图通常是路由函数,它们负责处理用户请求和返回响应。
python
@app.route('/')
def index():
db = get_db()
users = UserModel(db).get_users()
db.close()
return render_template('index.html', users=users)
@app.route('/add', methods=['POST'])
def add_user():
name = request.form['name']
age = request.form['age']
db = get_db()
UserModel(db).add_user(name, age)
db.close()
return redirect('/')
@app.route('/delete/<int:user_id>')
def delete_user(user_id):
db = get_db()
UserModel(db).delete_user(user_id)
db.close()
return redirect('/')
4. Controller(控制器)
在Flask中,控制器的概念不像在其他框架中那么明显,因为路由函数本身就充当了控制器的角色。但是,你可以通过创建一个控制器类来进一步分离逻辑。
python
class UserController:
def __init__(self, model):
self.model = model
def index(self):
return self.model.get_users()
def add_user(self, name, age):
self.model.add_user(name, age)
def delete_user(self, user_id):
self.model.delete_user(user_id_id)
然后,你可以在路由函数中使用这个控制器:
python
user_controller = UserController(UserModel(get_db()))
@app.route('/')
def index():
users = user_controller.index()
return render_template('index.html', users=users)
@app.route('/add', methods=['POST'])
def add_user():
name = request.form['name']
age = request.form['age']
user_controller.add_user(name, age)
return redirect('/')
5. HTML模板(视图)
创建一个简单的HTML模板来显示用户列表。
html
<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
<title>User List</title>
</head>
<body>
<h1>User List</h1>
<ul>
{% for user in users %}
<li>{{ user['name'] }} - {{ user['age'] }} <a href="/delete/{{ user['id'] }}">Delete</a></li>
{% endfor %}
</ul>
<form method="post" action="/add">
Name: <input type="text" name="name"> Age: <input type="text" name="age">
<input type="submit" value="Add User">
</form>
</body>
</html>
这个示例展示了如何在Flask应用中使用SQLite 3数据库实现MVC模式。模型负责数据库操作,视图负责渲染HTML模板,而控制器则处理用户请求并调用模型和视图。这种分离使得代码更加模块化,易于维护和扩展。