3.flask-sqlalchemy ORM库

介绍

Flask-SQLAlchemy是一个用于Flask的扩展,它提供了一个便捷的方式来处理数据库操作。Flask-SQLAlchemy基于SQLAlchemy,一个功能强大的Python SQL工具包和对象关系映射(ORM)系统

官网文档:http://www.pythondoc.com/flask-sqlalchemy/

一.安装

复制代码
pip install flask-sqlalchemy

二.flask-sqlalchemy基本使用

python 复制代码
from flask import Flask  
from flask_sqlalchemy import SQLAlchemy  
  
app = Flask(__name__)  
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost/bruce_demo'
db = SQLAlchemy(app)


  

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 = db.Column(db.String(120), nullable=False)
if __name__ == '__main__':  
    db.create_all()
    users = db.session.query(User).filter_by(username='John').all()  
	for user in users:  
    	print(user.email)
    # 创建新用户对象  
	new_user = User(username='John', email='[email protected]', password='password')  
	db.session.add(new_user)  
	db.session.commit()  # 提交更改到数据库  
	  
	# 查询用户对象  
	john = User.query.filter_by(username='John').first()  
	print(john.email)

三.flask-sqlalchemy常用方法

复制代码
    db.create_all():创建数据库表。
    db.session.query(Model):创建查询对象,用于执行数据库查询。
    db.session.add(instance):将实例添加到数据库会话中。
    db.session.commit():提交更改到数据库。
    db.session.delete(instance):删除实例并提交更改。
    db.session.merge(instance):将实例合并到数据库会话中并提交更改。
    db.session.flush():执行数据库的flush操作,将所有的操作写入数据库。
    db.session.expunge(instance):从会话中驱逐实例。
    db.session.refresh(instance):刷新实例的属性,从数据库中获取最新数据。
    db.session.get_by(key, value):根据给定的键和值获取实例。
    db.session.filter_by(key=value):根据给定的键和值过滤会话中的实例。
    db.session.first():返回查询结果中的第一个实例。
    db.session.first_or_404():返回查询结果中的第一个实例,如果未找到则返回404错误。
    db.session.all():返回查询结果中的所有实例。
    db.session.count():返回查询结果中的实例数量。
    db.session.delete_all():删除会话中的所有实例并提交更改。
    db.session.flush_all():执行数据库的flush操作,将所有的操作写入数据库,并清空会话。
    db.relationship(RelatedModel):创建关联关系,将两个模型关联起来。
    db.backref(name, uselist=True):为关联关系创建一个反向引用,可以通过反向引用访问关联的实例。
    db.column_property(column):创建一个列属性,用于获取或计算特定列的值。
    db.SynonymProperty(name, column=None):创建一个同义词属性,用于获取或设置特定列的值。
    db.ext:提供扩展功能,例如关联数据缓存、继承策略等。

四.Flask-SQLAlchemy中的db.Column支持以下类型

复制代码
    Integer:普通整数,一般是32位。
    SmallInteger:取值范围小的整数,一般是16位。
    BigInteger:不限制精度的整数,可以是int或long类型。
    Float:浮点数。
    String:变长字符串。
    Text:大文本字段。
    Boolean:布尔类型。
    DateTime:日期和时间类型。
    Date:日期类型。
    Time:时间类型。
    JSON:JSON格式数据类型。
    ARRAY:数组类型。
    PickleType:Pickle类型,用于存储Python对象结构。
    LargeBinary:大二进制字段。
    Enum:枚举类型。
    ARRAY:数组类型。
    JSON:JSON格式数据类型。
    TypeDecorator:用于自定义数据类型。
此外,db.Column还支持SQLAlchemy核心的任何数据类型,你可以根据需要自定义数据类型

五.关系模型

5.1一对多关系(OneToMany)

一对多关系是指一个模型与另一个模型之间存在多对一的关系。在 Flask-SQLAlchemy 中,你可以使用 relationship() 方法来定义一对多关系。下面是一个示例

python 复制代码
from flask_sqlalchemy import SQLAlchemy  
  
db = SQLAlchemy()  
  
class User(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    name = db.Column(db.String(50))  
    email = db.Column(db.String(50))  
    posts = db.relationship('Post', backref='user', lazy='dynamic')  
  
class Post(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    title = db.Column(db.String(100))  
    content = db.Column(db.Text)

在上面的示例中,User 和 Post 之间存在一对多关系。每个用户可以有多个帖子,每个帖子都与一个用户关联。

5.2多对多关系(ManyToMany)

多对多关系是指多个模型之间存在多对多的关系。在 Flask-SQLAlchemy 中,你可以使用 secondary 参数来定义多对多关系。下面是一个示例

python 复制代码
from flask_sqlalchemy import SQLAlchemy  
  
db = SQLAlchemy()  
  
class User(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    name = db.Column(db.String(50))  
    email = db.Column(db.String(50))  
  
class Group(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    name = db.Column(db.String(50))  
  
user_group = db.Table('user_group',  
    db.Column('user_id', db.Integer, db.ForeignKey('user.id')),  
    db.Column('group_id', db.Integer, db.ForeignKey('group.id'))  
)  
  
User.groups = db.relationship('Group', secondary=user_group, backref='users', lazy='dynamic')

在上面的示例中,User 和 Group 之间存在多对多关系。每个用户可以属于多个组,每个组可以包含多个用户。通过 secondary 参数,我们定义了一个名为 user_group 的中间表来存储用户和组之间的关联关系

5.3多对一关系(ManyToOne)

多对一关系是指多个模型与另一个模型之间存在一对多的关系。在 Flask-SQLAlchemy 中,你可以使用 relationship() 方法来定义多对一关系。下面是一个示例

python 复制代码
from flask_sqlalchemy import SQLAlchemy  
  
db = SQLAlchemy()  
  
class User(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    name = db.Column(db.String(50))  
    email = db.Column(db.String(50))  
    role_id = db.Column(db.Integer, db.ForeignKey('role.id'))  
  
class Role(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    name = db.Column(db.String(50))  
    users = db.relationship('User', backref='role', lazy='dynamic')

在上面的示例中,User 和 Role 之间存在多对一关系。多个用户可以拥有一个角色,每个角色可以与多个用户关联。通过外键约束 role_id,我们将用户与角色关联起来

六.常用约束

选项名

常用的查询和过滤方法

filter()使用指定的规则过滤记录,返回新产生的查询对象

filter_by()使用指定规则过滤记录(以关键字表达式的形式),返回新产生的查询对象

order_by()根据指定条件对记录进行排序,返回新产生的查询对象

group_by()根据指定条件对记录进行分组,返回新产生的查询对象

问题一:外键约束不能直接删除

sqlalchemy.exc.IntegrityError: (pymysql.err.IntegrityError) (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (pearadminflask.pt_renewal, CONSTRAINT pt_renewal_ibfk_1 FOREIGN KEY (course_id) REFERENCES pt_course (id))')

SQL: DELETE FROM pt_course WHERE pt_course.id = %(id_1)s

parameters: {'id_1': '110'}

复制代码
#一对多
#班级:学生=1:N
#班级表
class Grade(db.Model):
    __tablename__='grade'#表名
    id = db.Column(db.Integer, primary_key=True,autoincrement=True)
    name = db.Column(db.String(30), unique=True)

    #建立关联
    #第1个参数:关联的模型名(表)
    #第2个参数:反向引用的名称,grade对象
    #让student去反过来得到grade对象的名称
    #第3个参数:懒加载
    #students
    students=db.relationship('Student',backref='grade',lazy=True)


#学生表
class Student(db.Model):
    __tablename__ = 'student'  # 表名
    id = db.Column(db.Integer, primary_key=True,autoincrement=True)

    name = db.Column(db.String(30), unique=True)

    age = db.Column(db.Integer)
    #外键
    gradeid=db.Column(db.Integer,db.ForeignKey(Grade.id))
item.id,item.name,item.age,item.gradeid,item.grade,item.grade.id,item.grade.name

#多对多
#用户:电影 =N:M


#中间表:收藏表
collect=db.Table(
    'collects',
    db.Column('user_id',db.Integer,db.ForeignKey('usermodel.id'),primary_key=True),
    db.Column('movie_id',db.Integer,db.ForeignKey('movie.id'),primary_key=True),
)
#用户表
class UserModel(db.Model):
    __tablename__='usermodel'#表名
    id = db.Column(db.Integer, primary_key=True,autoincrement=True)
    name = db.Column(db.String(30))
    age=db.Column(db.Integer)

#电影表
class Moive(db.Model):
    __tablename__='movie'#表名
    id = db.Column(db.Integer, primary_key=True,autoincrement=True)
    name = db.Column(db.String(30))
    #关联
    #secondary=collect :设置中间表
    """
    layz属性
    懒加载,可以延迟在使用关联属性的时候才建立关联
    lazy='dynamic'会返回一个query对象,查询集,可以继续使用其他查询方法,如all()
    lazy='select'首次访问到属性的时候,就会全部加载该属性的数据
    lazy='joined'在对关联的两个表进行join操作,从而获取到所有相关的对象
    lazy=True返回一个可用的列表对象,同select
    """
    users=db.relationship('UserModel',backref="movies",layz=True,secondary=collect)

用户收藏电影
user=UserModel.query.get(1)
moive=Moive.query.get(1)

user.movies.append(movie)
db.session.commit()

#查找某用户收藏的所有电影
user=UserModel.query.get(1)
print(user.moives)

#查找收藏了某电影的所有用户
moive=Movie.query.get(1)
print(moive.users)

#级联删除
user=UserModel.query.get(1)
db.session.delete(user)
db.session.commit()
相关推荐
王强你强1 分钟前
MySQL 高级查询:JOIN、子查询、窗口函数
数据库·mysql
草巾冒小子2 分钟前
brew 安装mysql,启动,停止,重启
数据库·mysql
用户6279947182629 分钟前
南大通用GBase 8c分布式版本gha_ctl 命令-HI参数详解
数据库
The Future is mine16 分钟前
Python计算经纬度两点之间距离
开发语言·python
斯汤雷18 分钟前
Matlab绘图案例,设置图片大小,坐标轴比例为黄金比
数据库·人工智能·算法·matlab·信息可视化
九月镇灵将18 分钟前
GitPython库快速应用入门
git·python·gitpython
SQLplusDB25 分钟前
Oracle 23ai Vector Search 系列之3 集成嵌入生成模型(Embedding Model)到数据库示例,以及常见错误
数据库·oracle·embedding
喝醉酒的小白1 小时前
SQL Server 可用性组自动种子设定失败问题
数据库
兔子的洋葱圈1 小时前
【django】1-2 django项目的请求处理流程(详细)
后端·python·django
chem41111 小时前
Conmon lisp Demo
服务器·数据库·lisp