资讯专栏INFORMATION COLUMN

Flask-SQLAlchemy 学习总结

whataa / 1453人阅读

摘要:初始化和配置对象关系映射。的则需要在中声明。例如配置信息中指出是可以绑定多个数据库引擎。是通过解决一对多的关系。将会返回学院学生人数将会返回学生的学院信息的类实例。处理关系对象查询中有详细的说明。

初始化和配置

ORM(Object Relational Mapper) 对象关系映射。指将面对对象得方法映射到数据库中的关系对象中。
Flask-SQLAlchemy是一个Flask扩展,能够支持多种数据库后台,我们可以不需要关心SQL的处理细节,操作数据库,一个基本关系对应一个类,而一个实体对应类的实例对象,通过调用方法操作数据库。Flask-SQLAlchemy有很完善的文档。

Flask-SQLAlchemy是通过URL指定数据库的连接信息的。
初始化的两种方法如下(以连接Mysql数据库为例):

from flask_sqlalchemy import SQLAlchemy
from flask import FLask
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = 
    "mysql://root:12345@localhost/test"
db = SQLAlchemy(app)

或者

from flask_sqlalchemy import SQLAlchemy
from flask import FLask
db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    db.init_app(app)
    return app

两者的区别在于:第一种不需要启动flask的app_context;但是第二种方法则需要,因为可能会创建多个Flask应用,但是我的理解是一般地开发时,Flask实例是延迟创建的,因为在运行时难以修改配置信息,这种方法符合这种情况。
Flask-SQLAlchemy的则需要在Flask.config中声明。更多详细信息需要查配置。例如配置信息中指出SQLAlchemy是可以绑定多个数据库引擎。再例如:在新浪SAE云平台开发个人博客时遇到gone away这种问题就需要添加SQLALCHEMY_POOL_RECYCLE信息,新浪开发者文档中有说明。


SQLALchemy处理 对象->关系

SQLAlchemy是如何处理对象到关系的?实例来自于数据库系统概论内容。

简单实例

创建学生students表

class Student(db.Model):
    __tablename__ = "students" #指定表名
    sno = db.Column(db.String(10), primary_key=True)
    sname = db.Column(db.String(10))
    sage = db.Column(db.Integer)

API文档说明创建对象需要继承db.Model类关联数据表项,db.Model类继承Query类提供有数据查询方法;__tablename__指定数据库的表名,在Flask-SQLAlchemy中是可省的。Column指定表字段。

SQLAlchemy支持字段类型有:

类型名 python类型 说明
Integer int 普通整数,32位
Float float 浮点数
String str 变长字符串
Text str 变长字符串,对较长字符串做了优化
Boolean bool 布尔值
PickleType 任何python对象 自动使用Pickle序列化

来源于Simple Example,Flask Web开发有更详细的内容。
其余的参数指定属性的配置选项,常用的配置选项如下:

选项名 说明
primarykey 如果设为True,表示主键
unique 如果设为True,这列不重复
index 如果设为True,创建索引,提升查询效率
nullable 如果设为True,允许空值
default 为这列定义默认值

如使用default默认time属性如下:

time = db.Column(db.Date, default=datetime.utcnow)

说明default可以接受lambda表达式。

一对多

按创建单张表的方法,创建学院Deptment表

class Deptment(db.Model):
    __tablename__ = "deptments"
    dno = db.Column(db.Integer, primary_key=True)
    dname = Sname = db.Column(db.String(10),index=True)

学院和学生是一对多的关系。Flask-SQLAlchemy是通过db.relationship()解决一对多的关系。在Dept中添加属性,代码如下:

class Deptment(db.Model):
    ...
    students = db.relationship("Student", backref="dept")
    
    
class Student(db.Model):
    ...
    dept_no = db.Column(db.Integer, db.ForeignKey("deptments.dno"))

表的外键由db.ForeignKey指定,传入的参数是表的字段。db.relations它声明的属性不作为表字段,第一个参数是关联类的名字,backref是一个反向身份的代理,相当于在Student类中添加了dept的属性。例如,有Deptment实例dept和Student实例stu。dept.students.count()将会返回学院学生人数;stu.dept.first()将会返回学生的学院信息的Deptment类实例。一般来讲db.relationship()会放在这一边。

多对多

多对多的关系可以分解成一对多关系,例如:学生选课,学生与课程之间的关系:

sc = db.Table("sc",
    db.Column("sno", db.String(10), db.ForeignKey("students.sno"))
    db.Column("cno",db.String(10), db.ForeignKey("courses.cno"))
    )
    
Class Course(db.Model):
    __tablename__ = "courses"
    cno = db.Column(db.String(10), primary_key=True)
    cname = db.Column(db.String(10), index=True)
    students = db.relationship("Student",
         secondary=sc,
         backref=db.backref("course",lazy="dynamic"),
         lazy="dynamic"
         )

sc表由db.Table声明,我们不需要关心这张表,因为这张表将会由SQLAlchemy接管,它唯一的作用是作为students表和courses表关联表,所以必须在db.relationship()中指出sencondary关联表参数。lazy是指查询时的惰性求值的方式,这里有详细的参数说明,而db.backref是声明反向身份代理,其中的lazy参数是指明反向查询的惰性求值方式,SQLAlchemy鼓励这种方式声明多对多的关系。

但是如果关联表中有自定义的字段,如sc表中添加成绩字段则需要更改表声明方式,将sc更改为继承db.Model的对象并设置sc:courses = 1:nsc:student = 1:n的关系。


SQLALchemy处理 关系->对象

Flask-SQLAlchemy查询中有详细的说明。创建关系后该如何查询到对象?

SQLAlchemy有查询过滤器如下:

过滤器 说明
filter() 把过滤器添加到原查询,返回新查询
filter_by() 把等值过滤器添加到原查询,返回新查询
limit() 使用指定值限制原查询返回的结果数量,返回新查询
offset() 偏移原查询返回的结果,返回新查询
order_by() 排序返回结果,返回新查询
groupby() 原查询分组,返回新查询

这些过滤器返回的结果都是一个新查询,我的理解是这些查询其实是生成的SQL语句,lazy的惰性求值方式也体现在查询上,而这些语句不能生成需要查询的对象,需要调用其他的方法生成对象。

SQL查询执行函数:

方法 说明
all() 以列表形式返回结果
first() 返回第一个结果,如果没有返回None
first_or_404() 返回第一个结果,如果没有抛出404异常
get() 返回主键对应记录,没有则返回None
get_or_404() 返回主键对应记录,如果没有抛出404异常
count() 返回查询结果数量
paginate() 返回paginate对象,此对象用于分页

个人博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37806.html

相关文章

  • 关于Flask-SQLAlchemy事务提交有趣的探讨

    摘要:最近在开发的时候遇到这样一个问题我就好奇了这样还报不在中的错没有显示调用啊加一行测试无奈,一个一个翻到之间调用的每一个函数,终于在找到可疑点但是这里也没有显式提交。为什么接下来总结下大神们的探讨。 最近在开发mdwiki的时候遇到这样一个问题.Post is unbond to session.我就好奇了 post=Post.query.filter_by(location=locat...

    BlackHole1 评论0 收藏0
  • Flask 插件系列 - Flask-SQLAlchemy

    摘要:程序中最常用的莫过于关系型数据库了,也称数据库。对象是类的实例,表示程序使用的数据库。本文由发表于个人博客,采用自由转载保持署名非商用禁止演绎协议发布。非商业转载请注明作者及出处。本文标题为插件系列本文链接为更多阅读 简介 Web 开发中,一个重要的组成部分便是数据库了。Web 程序中最常用的莫过于关系型数据库了,也称 SQL 数据库。另外,文档数据库(如 mongodb)、键值对数据...

    LoftySoul 评论0 收藏0
  • 从零开始用 Flask 搭建一个网站(二)

    摘要:从零开始用搭建一个网站一介绍了如何搭建环境,以及应用基本项目结构。我们要搭建的网站是管理第三方集成的控制台,类似于。我们先定义一个用户模型然后在文件夹下创建一个文件。 从零开始用 Flask 搭建一个网站(一) 介绍了如何搭建 Python 环境,以及 Flask 应用基本项目结构。我们要搭建的网站是管理第三方集成的控制台,类似于 Slack。 本篇主要讲解数据如何在 Flask 应用...

    Coly 评论0 收藏0
  • Flask Web Development —— 数据库(上)

    摘要:数据库关系数据库将数据保存在表中来模拟应用程序中不同的实体。这些行之间的连接称作关系,也是关系数据库模型的基础。就像这个示例中看到的那样,关系数据库存储数据高效且避免重复。最好的例子就是,支持一组关系数据库引擎,包括流行的和。 数据库就是有组织的存储应用程序数据,然后查询检索指定需要的那部分。大部分web应用程序都采用基于关系模型的数据库,也称作结构化查询语言(SQL)数据库。但是最近...

    skinner 评论0 收藏0

发表评论

0条评论

whataa

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<