跳到主要内容

数据库集成

Flask-SQLAlchemy 是 Flask 最常用的数据库扩展,提供了 ORM 功能。

安装

pip install flask-sqlalchemy flask-migrate

基本配置

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

app = Flask(__name__)

# 数据库配置
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)
migrate = Migrate(app, db)

定义模型

from datetime import datetime

class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(128))
created_at = db.Column(db.DateTime, default=datetime.utcnow)

# 关系
posts = db.relationship('Post', backref='author', lazy=True)

def __repr__(self):
return f'<User {self.username}>'

class 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)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

def __repr__(self):
return f'<Post {self.title}>'

常用字段类型

类型说明
db.Integer整数
db.String(n)字符串,最大长度 n
db.Text长文本
db.DateTime日期时间
db.Float浮点数
db.Boolean布尔值
db.PickleType存储 Python 对象
db.LargeBinary二进制数据

数据库操作

创建表

# 创建所有表
with app.app_context():
db.create_all()

# 创建记录
user = User(username='john', email='[email protected]')
db.session.add(user)
db.session.commit()

# 批量添加
users = [
User(username='alice', email='[email protected]'),
User(username='bob', email='[email protected]')
]
db.session.add_all(users)
db.session.commit()

# 查询所有
users = User.query.all()

# 根据主键查询
user = User.query.get(1)

# 条件查询
user = User.query.filter_by(username='john').first()
users = User.query.filter(User.email.endswith('@example.com')).all()

# 复杂查询
from sqlalchemy import and_, or_

users = User.query.filter(
and_(User.username.like('j%'), User.email.contains('example'))
).all()

# 排序
users = User.query.order_by(User.created_at.desc()).all()

# 分页
pagination = User.query.paginate(page=1, per_page=10, error_out=False)
users = pagination.items
total = pagination.total
pages = pagination.pages

user = User.query.get(1)
user.email = '[email protected]'
db.session.commit()

user = User.query.get(1)
db.session.delete(user)
db.session.commit()

数据库迁移

初始化迁移

flask db init

创建迁移

flask db migrate -m "Initial migration"

应用迁移

flask db upgrade

回滚

flask db downgrade

关系

一对多

class Department(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
employees = db.relationship('Employee', backref='department', lazy=True)

class Employee(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
dept_id = db.Column(db.Integer, db.ForeignKey('department.id'))

多对多

# 关联表
student_course = db.Table('student_course',
db.Column('student_id', db.Integer, db.ForeignKey('student.id'), primary_key=True),
db.Column('course_id', db.Integer, db.ForeignKey('course.id'), primary_key=True)
)

class Student(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
courses = db.relationship('Course', secondary=student_course, backref='students')

class Course(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))

一对一

class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80))
profile = db.relationship('Profile', backref='user', uselist=False)

class Profile(db.Model):
id = db.Column(db.Integer, primary_key=True)
bio = db.Column(db.Text)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), unique=True)

查询方法

# 限制和偏移
users = User.query.limit(10).offset(20).all()

# 计数
count = User.query.filter_by(username='john').count()

# 聚合
from sqlalchemy import func

result = db.session.query(
func.count(User.id),
func.max(User.created_at)
).first()

# 分组
results = db.session.query(
User.username,
func.count(Post.id)
).join(Post).group_by(User.id).all()

# 连接
posts = Post.query.join(User).filter(User.username == 'john').all()

应用工厂模式

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

db = SQLAlchemy()
migrate = Migrate()

def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

db.init_app(app)
migrate.init_app(app, db)

return app

下一步

学习用户认证和会话管理。