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

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

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

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)

或者mysql

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信息,新浪开发者文档中有说明。sql

SQLALchemy处理 对象->关系

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

简单实例

建立学生students表flask

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指定表字段。segmentfault

SQLAlchemy支持字段类型有:app

类型名 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表达式。spa

一对多

按建立单张表的方法,建立学院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对象,此对象用于分页
相关文章
相关标签/搜索