首先,我们需要为Flask应用配置数据库连接并初始化SQLAlchemy。Flask使用Flask-SQLAlchemy扩展来简化与数据库的交互。
bashpip install Flask-SQLAlchemy
pythonfrom flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 配置数据库URI,Flask-SQLAlchemy支持多种数据库,如SQLite、MySQL、PostgreSQL等
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' # SQLite数据库
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 禁用信号系统,减少不必要的开销
app.secret_key = 'your_secret_key' # 用于会话加密
# 初始化SQLAlchemy
db = SQLAlchemy(app)
在Flask中,模型通常是与数据库表一一对应的Python类。SQLAlchemy会自动将类的属性映射为数据库表的列。
pythonclass User(db.Model):
id = db.Column(db.Integer, primary_key=True) # 主键
username = db.Column(db.String(120), unique=True, nullable=False) # 用户名,必须唯一且不能为空
email = db.Column(db.String(120), unique=True, nullable=False) # 邮箱,必须唯一且不能为空
password = db.Column(db.String(60), nullable=False) # 密码
def __repr__(self):
return f"User('{self.username}', '{self.email}')"
db.Column: 用于定义数据库表的字段。参数包括数据类型(如Integer, String),约束(如primary_key, nullable, unique)。__repr__: 用于定义对象的字符串表示,方便调试时查看对象。在定义模型后,需要在数据库中创建对应的表。你可以使用db.create_all()来创建所有定义的表。
pythonwith app.app_context():
db.create_all() # 创建数据库表
你可以通过创建模型实例并将其添加到数据库会话(session)中来插入数据。
python@app.route('/create_user')
def create_user():
user = User(username='johndoe', email='johndoe@example.com', password='password123')
db.session.add(user) # 将用户对象添加到会话中
db.session.commit() # 提交事务,将数据保存到数据库
return 'User created!'
Flask-SQLAlchemy提供了许多用于查询数据库的方法。你可以使用query对象进行各种查询操作。
python@app.route('/all_users')
def all_users():
users = User.query.all() # 查询所有用户
return '<br>'.join([user.username for user in users]) # 显示所有用户的用户名
python@app.route('/get_user/<int:id>')
def get_user(id):
user = User.query.get_or_404(id) # 根据ID查询用户,如果没有找到,返回404
return f'Username: {user.username}, Email: {user.email}'
python@app.route('/get_user_by_email/<string:email>')
def get_user_by_email(email):
user = User.query.filter_by(email=email).first() # 按照邮箱查询第一个匹配的用户
if user:
return f'Username: {user.username}, Email: {user.email}'
return 'User not found'
python@app.route('/get_users_sorted')
def get_users_sorted():
users = User.query.filter_by(username='johndoe').order_by(User.email.desc()).all() # 按邮箱降序排序
return '<br>'.join([f'{user.username}: {user.email}' for user in users])
你可以通过获取模型对象,修改其属性,再提交事务来更新数据。
python@app.route('/update_user/<int:id>')
def update_user(id):
user = User.query.get_or_404(id) # 获取用户
user.email = 'newemail@example.com' # 更新邮箱
db.session.commit() # 提交更新
return f'Updated user {user.username} with new email: {user.email}'
要删除数据,你需要从数据库会话中删除模型对象,然后提交事务。
python@app.route('/delete_user/<int:id>')
def delete_user(id):
user = User.query.get_or_404(id) # 获取用户
db.session.delete(user) # 删除用户
db.session.commit() # 提交删除
return f'Deleted user {user.username}'
在Flask应用中,常常需要处理不同模型之间的关系,例如一对多、多对多等关系。SQLAlchemy通过外键(ForeignKey)来实现模型之间的关联。
pythonclass Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) # 外键关联到User模型
user = db.relationship('User', backref=db.backref('posts', lazy=True)) # 定义关系
user_id字段是Post表的外键,指向User表的id。db.relationship定义了在User和Post之间的一对多关系。backref允许我们通过User对象访问posts。python@app.route('/user_posts/<int:user_id>')
def user_posts(user_id):
user = User.query.get_or_404(user_id)
posts = user.posts # 获取用户的所有文章
return '<br>'.join([post.title for post in posts])
pythonclass Course(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
courses = db.relationship('Course', secondary='enrollment', backref=db.backref('students', lazy=True))
class Enrollment(db.Model):
id = db.Column(db.Integer, primary_key=True)
student_id = db.Column(db.Integer, db.ForeignKey('student.id'), nullable=False)
course_id = db.Column(db.Integer, db.ForeignKey('course.id'), nullable=False)
Enrollment表充当多对多关系的关联表。python@app.route('/student_courses/<int:student_id>')
def student_courses(student_id):
student = Student.query.get_or_404(student_id)
courses = student.courses # 获取学生所修的所有课程
return '<br>'.join([course.name for course in courses])
数据库索引对于提高查询效率非常重要,尤其是在大型数据集上。你可以为模型字段创建索引,以提高查询性能。
pythonclass User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(120), unique=True, nullable=False, index=True) # 在用户名上创建索引
email = db.Column(db.String(120), unique=True, nullable=False, index=True) # 在邮箱上创建索引
index=True:创建索引,适用于查询频繁的字段。如果你需要多个字段联合查询时加速查询,可以创建联合索引。
pythonclass User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(120), nullable=False)
email = db.Column(db.String(120), nullable=False)
__table_args__ = (
db.Index('ix_username_email', 'username', 'email'), # 创建联合索引
)
当你查询大量数据时,可以通过lazy加载来优化查询,减少不必要的查询。
pythonclass User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(120), nullable=False)
posts = db.relationship('Post', lazy='dynamic') # 使用动态加载
@app.route('/user_posts/<int:user_id>')
def user_posts(user_id):
user = User.query.get_or_404(user_id)
posts = user.posts.all() # 执行查询
return '<br>'.join([post.title for post in posts])
本文作者:晏秋
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!