Flask-SQLAlchemy 配置,处理对象-关系,一对多,多对多

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:[email protected]/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 ExampleFlask 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对象,此对象用于分页

时间: 2024-08-25 16:34:19

Flask-SQLAlchemy 配置,处理对象-关系,一对多,多对多的相关文章

hibernate对象关系实现(三)多对多实现

单向n-n:(catogory-item)一个类别对应多个条目,一个条目对应多个类别 a.以类别类中有条目的集合的引用为例: b.数据库中的体现:建立一个新表,以类别和条目的主键关联的外键做新表的联合主键. c.映射配置:在类别表中配置外键映射关系 d测试: 保存 将执行四条插入语句将种类和条目插入后再执行四条插入语句将关联关系插入category_item目表: 获取: 获取类别关联对象集合是延迟加载的: 获取条目集合数据时候,采用内连接的方式,即关系表和条目表的内连接, 二.对于双向的多对多

flask SQLAlchemy中一对多的关系实现

SQLAlchemy是Python中比较优秀的orm框架,在SQLAlchemy中定义了多种数据库表的对应关系, 其中一对多是一种比较常见的关系.利用flask sqlalchemy实现一对多的关系如下: 1. 建立数据库的模型 在本次试验中建立三个表: user, phone ,atttr.user 和phone, phone 和atttr均为一对多的关系.实现如下: #!/usr/bin/env python # -*- coding: utf-8 -*- from flask import

MyBatis的对象关系映射---一对多N+1策略★★★★★

在实际开发中,一个业务可能涉及到多个数据表的查询,那么多表查询就涉及连接查询(等值连接), 等值连接 表与表之间有一个外键关键,但是程序中最终获取的表封装的对象, 对象与对象之间是没有外键关系的,对象和对象之间只有依赖关系: 对象之间关系主要是四种: 一对一 关系一个人对应身份证id,一个QQ号对应一个QQ空间 一对多 关系 一个部门对应多个员工 多对一 关系 多个员工对应一个部门 多对多 关系 多个学生对应多个老师,多个学生对应多个课程 什么关系应该从哪个对象作为中心点来看 一对多, 以one

Flask【第八章】:Flask之flask实例化配置以及flask对象配置

Flask之flask实例化配置以及flask对象配置 flask是一个非常灵活且短小精干的web框架,那么灵活性从什么地方体现呢? 一.flask实例化配置 有一个神奇的东西叫flask配置,这个东西要怎么用呢?它能给我们带来怎么样的方便呢? 首先展示一下: from flask import Flask app = Flask(__name__) # type:Flask app.config["DEBUG"] = True 这句app.config["DRBUG&quo

Hibernate (开放源代码的对象关系映射框架)

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久

Hibernate之配置文件以及对象关系映射文件了解

声明:CSDN不知道怎么了,有时候就是发表不了博文.本来就是一天一篇博文,最近搞的我很郁闷.有时候一天,有时候两三天都不能发.这就属于不可抗力.没办法的,啥时能发,我就发了. 一.学习案例:关于hibernate的配置文件以及对象关系映射文件的了解. 二.案例分析: a)hibernate配置文件(hibernate.cfg.xml) 1.hibernate.dialect:数据库使用的SQL方言 2.hiebrnate.connection.driver_class:数据库的驱动程序 3.hi

Flask SQLAlchemy & model

Flask-SQLAlchemy Flask-SQLAlchemy库让flask更方便的使用SQLALchemy,是一个强大的关系形数据库框架,既可以使用orm方式操作数据库,也可以使用原始的SQL命令. 配置Flask-SQLAlchemy 示例: MySQL: mysql://username:[email protected]/database 定义模型 from sqlalchemy import Column, Integer, MetaData, VARCHAR from flask

Hibernate (开放源代码的对象关系映射框架)介绍

Hibernate (开放源代码的对象关系映射框架) 编辑 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hiberna

死去活来,而不变质:Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?

写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?>博文中,探讨的是如何聚焦领域模型(抛开一些干扰因素,才能把精力集中在领域模型的设计上)?需要注意的是,上一篇我讲的并不是如何设计领域模型(本篇也是)?而是如何聚焦领域模型,领域模型的设计是个迭代过程,不能一概而论,还在路上. 当有一个简单的领域模型用例,完成一个从上而下过程的时候,就需要对领域模型和数据库进行对象关系