美文网首页
Flask-SQLAlchemy 基本使用

Flask-SQLAlchemy 基本使用

作者: Whyn | 来源:发表于2019-02-06 00:15 被阅读0次

    简介

    Flask-SQLAlchemy 是 Python Web 框架 Flask 的一个扩展,简化了在 Flask 中对 ORM 数据库框架 SQLAlchemy 的操作。

    基本使用

    • 一个最小型的应用:对于大多数只有一个 Flask 的应用来说,需要做的就是为 Flask 实例选择加载配置,然后把 SQLlchemy 实例传递给它即可:
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    
    # need to install pymysql first if using mysql
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:password@localhost/test'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    db = SQLAlchemy(app)
    
    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(80), unique=True)
        email = db.Column(db.String(120), unique=True)
    
        def __init__(self, username, email):
            self.username = username
            self.email = email
    
        def __repr__(self):
            return '<User %r>' % self.username
    
    
    # create tables
    db.create_all()
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    

    首先,要让 Flask-SQLAlchemy 根据模型类创建数据库。db.create_all()函数将寻找所有db.Model的子类,然后在数据库中创建对应的表,如果数据库中相应表已存在,则db.create_all()不会重新创建或者更新相应的表。
    :上面的代码中我们已经在 MySql 数据库中创建了一个表user,接下来我们添加几条数据到user表中:

    from yourapplication import User
    admin = User(username='admin', email='admin@example.com')
    guest = User(username='guest', email='guest@example.com')
    
    db.session.add(admin)
    db.session.add(guest)
    db.session.commit()
    

    :下面我们访问这个表,看下数据是否已插入成功:

    >>> User.query.all()
    [<User 'admin'>, <User 'guest'>]
    >>> User.query.filter_by(username='admin').first()
    <User 'admin'>
    

    :下面我们删除掉username=guest这条数据:

    guest = User.query.filter_by(username='guest').first()
    db.session.delete(guest)
    db.session.commit()
    

    :下面我们修改username=admin这条数据,让其邮箱变更为admin@qq.com

    # get User admin data from primary key
    admin = User.query.get(1)
    admin.email = 'admin@qq.com'
    db.session.add(admin) # not necessary
    db.session.commit()
    

    更多 Flask-SQLAlchemy 对数据库进行增删改查的操作,请查看:Select, Insert, Delete

    数据库表间关系简解

    在关系型数据中,表与表之间存在三种关系:一对多,一对一和多对多。由于关系是建立在多个表之间的,因此当我们声明一个表单模型时,与之关联的表可能并未建立,因此可以使用字符串指向未创建的关联表名。下面简单介绍下这三种关系在 Flask-SQLAlchemy 中的实现方式:

    • 一对多:最常见的表间关系。假设现在有两张表:学生表students和班级表classesstudents存储学生信息,classes存储班级信息。每个学生都对应一个班级,每个班级对应多个学生,因此,班级表classes与学生表stuents是一对多关系:
    class Student(db.Model):
        __tablename__ = 'students'
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(64), nullable=False)
        class_id = db.Column(db.Integer, db.ForeignKey('classes.id'))
    
        def __repr__(self):
            return '<Student: %r>' % self.name
    
    
    class Classe(db.Model):
        __tablename__ = 'classes'
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(64), nullable=False)
        students = db.relationship('Student', backref='_class', lazy=True)
    
        def __repr__(self):
            return '<Class: %r>' % self.name
    

    上面代码中,我们使用relationship方法建立了classes表和students表之间的一对多联系(一个班级对应多个学生),其中的backref为反向关系定义,为Studnet模型添加了一个_class属性,表示学生对应的班级(Student()._class)。而lazy指定了加载数据的时机,其共有四种选择:
     • select/True:默认属性。按需加载,即在访问到属性的时候,才会全部加载该属性的数据(即:class01.students返回一个学生列表)。
     • joined/False:加载记录,但使用联结。
     • subquery:与joined类似,立即加载,但使用子查询。
     • dynamic:不加载记录,而是提供加载记录的查询,即生成一个query对象,方便进行条件过滤(即:class01.students返回一个query)。
    下面对我们创建的两个表进行数据注入,并进行使用,如下所示:

    # insert data
    stu01 = Student(name="one")
    stu02 = Student(name="two")
    stu03 = Student(name="three")
    
    class01 = Classe(name="class01", students=[stu01])
    class02 = Classe(name="class02", students=[stu02, stu03])
    
    # update db
    db.session.add_all([stu01, stu02, stu03, class01, class02])
    db.session.commit()
    
    # query
    stu = Student.query.filter_by(_class=class01).first()
    print(stu)
    print(stu._class)
    
    cls02 = Classe.query.filter_by(name='class02').first()
    print(cls02.students)
    
    • 一对一关系:只需为relationship添加参数uselist=False即可建立一对一关系。

    • 多对多关系:若要定义多对多关系,需要借助一张中间表进行实现。强烈建议使用一张真实的表而不是表模型作为中间表。

    tags = db.Table('tags',
        db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True),
        db.Column('page_id', db.Integer, db.ForeignKey('page.id'), primary_key=True)
    )
    
    class Page(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        tags = db.relationship('Tag', secondary=tags, lazy='subquery',
            backref=db.backref('pages', lazy=True))
    
    class Tag(db.Model):
        id = db.Column(db.Integer, primary_key=True)
    

    更多详细信息,请查看:relationships

    参考

    相关文章

      网友评论

          本文标题:Flask-SQLAlchemy 基本使用

          本文链接:https://www.haomeiwen.com/subject/qilmsqtx.html