• 3.flask-sqlalchemy ORM库


    介绍

    Flask-SQLAlchemy是一个用于Flask的扩展,它提供了一个便捷的方式来处理数据库操作。Flask-SQLAlchemy基于SQLAlchemy,一个功能强大的Python SQL工具包和对象关系映射(ORM)系统
    官网文档:http://www.pythondoc.com/flask-sqlalchemy/

    一.安装

    pip install flask-sqlalchemy
    
    • 1

    二.flask-sqlalchemy基本使用

    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='john@example.com', password='password')  
    	db.session.add(new_user)  
    	db.session.commit()  # 提交更改到数据库  
    	  
    	# 查询用户对象  
    	john = User.query.filter_by(username='John').first()  
    	print(john.email)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    三.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:提供扩展功能,例如关联数据缓存、继承策略等。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    四.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核心的任何数据类型,你可以根据需要自定义数据类型
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    五.关系模型

    5.1一对多关系(OneToMany)

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

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

    5.2多对多关系(ManyToMany)

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

    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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

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

    5.3多对一关系(ManyToOne)

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

    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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在上面的示例中,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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    #多对多
    #用户:电影 =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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
  • 相关阅读:
    c++ 计算五分钟内的平均值
    设计模式之观察者模式(十四)
    “五之链”第十六期沙龙活动在呆马科技成功举办
    Day695.Spring Boot如何使用内嵌式的Tomcat和Jetty -深入拆解 Tomcat & Jetty
    脑机接口003 | 马斯克称已实现与云端的虚拟自己对话,相关概念股份大涨
    算法的概述
    原油等特殊期货开户要求和豁免
    boost 之计算机的时间-chrono
    Scala——While和do..While循环控制
    基于非支配排序遗传算法的多目标水光互补优化调度附Matlab代码
  • 原文地址:https://blog.csdn.net/qq_44623314/article/details/132612418