Flask 框架学习(三)
2016-03-14 16:10
302 查看
( 上接Flask 框架学习(二) )
这里要引入一个概念。
听着就感觉很蛋疼,我们即将使用的Flask-SQLAlchemy扩展就是一个已经封装了关系对象映射(ORM)的一个插件。
而ORMs允许数据库程序用对象的方式替代表和SQL语句。面向对象的操作被ORM转化为数据库命令。这样就意味着,不用sql语句,让Flask-SQLAlchemy为我们执行sql语句。
简单的说,就是如SQLAlchemy或MongoEngine让你像操作常规Python对象那样,而不是数据库实体表、文档或查询语句。
应该稍微明白一点了,在之后的例子中能够很快就明白的。
此处我们以链接Mysql为例,在我们使用数据库的时候,需要在Flask配置对象中的
下述为.py文件的配置部分:
在
hostname是指托管MySQL服务的服务器(本地localhost或是远程服务器)
database指出要使用的数据库名
username和 password是数据库用户凭证
我的URL配置是
即我使用的用户名是root,而且没有密码,然后连接本地服务器,使用了名为flask的数据库。
现在我们例子如下:
来解释下上面的代码,
- 上述两个类就是我们的两个表,在ORM的背景下,我们将两个temp1表和temp2表抽象成了两个类,或是说两个模型。
- _table_类变量定义数据库中表的名称,缺省的复制
- 而其他的类变量则是
db.Column的其他参数大概如下,都是列的一些属性,了解SQL的应该能够直接看懂:
小技巧,类定义中可以重载一下repr函数,就我个人的习惯来说,我经常犯各种错误,而且自己找不出来,这个时候就需要动用到ide来调试,这时候重写repr函数的优势就显示出来了…….
上述应该比较好理解,添加给temp2一个tempfk的外键,链接的是temp1中的id列,
PS:这里我们重写了repr函数,具体的用途在之后会说的。
这里的演示我们直接在cmd中进行,然后一边配置mysql客户端来检验。
直接调用
就可以创建出数据表,
确实成功了。
另一个
下面是插入数据
但是执行完上述语句之后还没有将数据写入Mysql
只是存于Python中,而且它们对应的id值还没有分配。
修改数据库的操作由Flask-SQLAlchemy提供的db.session数据库会话来管理。准备写入到数据库中的对象必须添加到会话中:
或是更简单点的:
为了写对象到数据库,需要通过它的commit()方法来提交会话:
运行之后观察MYSQL,发现数据已经写入:
这里发现我们之前没有对id赋值但是它却有值,而且该字段是
如果我们没有显示赋值是会从0自增的,当然肯定也是可以显示赋值的。
如果要修改会话中存在的值,例如我们添加了一个
我们想把name字段改成4321
那么直接
接下来是删除行
然后是返回行
Flask-SQLAlchemy为每个模型类创建一个query对象。最基本的查询模型是返回对应的表的全部内容:
大家看看这个query.all()函数返回值是不是很眼熟,这就是我们之前在sql_1.py里面重写的repr函数的结构啊。
使用过滤器可以配置查询对象去执行更具体的数据库搜索。在表一中找出name字段为’admin’的记录。
对于给定的查询还可以检查SQLAlchemy生成的原生SQL查询,并将查询对象转换为一个字符串:
还有另外一种方式来查询,如果我们知道了用户的id,我们可以使用下面的方式查找用户信息:
想更深入的学习,还是看原文档吧SQLAlchemy文档
4、数据库
SQLAlchemy文档4.1 引入
Flask在可使用的数据库包上没有限制,所以可以使用MySQL、Postgres、SQLite、Redis、MongoDB或者CouchDB等等任意一个。这里要引入一个概念。
ORM(对象关系映射,Object Relational Mapping)是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。
听着就感觉很蛋疼,我们即将使用的Flask-SQLAlchemy扩展就是一个已经封装了关系对象映射(ORM)的一个插件。
而ORMs允许数据库程序用对象的方式替代表和SQL语句。面向对象的操作被ORM转化为数据库命令。这样就意味着,不用sql语句,让Flask-SQLAlchemy为我们执行sql语句。
简单的说,就是如SQLAlchemy或MongoEngine让你像操作常规Python对象那样,而不是数据库实体表、文档或查询语句。
应该稍微明白一点了,在之后的例子中能够很快就明白的。
此处我们以链接Mysql为例,在我们使用数据库的时候,需要在Flask配置对象中的
SQLALCHEMY_DATABASE_URI键中进行配置。另一个有用的选项是
SQLALCHEMY_COMMIT_ON_TEARDOWN,可以设置为True来启用自动提交数据库更改在每个请求中。
下述为.py文件的配置部分:
from flask.ext.sqlalchemy import SQLAlchemy from flask import Flask app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] ="mysql://root:@localhost/flask" app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True db = SQLAlchemy(app)
在
SQLALCHEMY_DATABASE_URI键的配置时,规定使用url来确定数据库,几个常用数据库的配置URL如下:
hostname是指托管MySQL服务的服务器(本地localhost或是远程服务器)
database指出要使用的数据库名
username和 password是数据库用户凭证
我的URL配置是
mysql://root:@localhost/flask
即我使用的用户名是root,而且没有密码,然后连接本地服务器,使用了名为flask的数据库。
现在我们例子如下:
class temp1(db.model): __tablename__='temp1' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), unique=True) class temp2(db.Model): __tablename__ = 'temp2' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(100), unique=True)
来解释下上面的代码,
- 上述两个类就是我们的两个表,在ORM的背景下,我们将两个temp1表和temp2表抽象成了两个类,或是说两个模型。
- _table_类变量定义数据库中表的名称,缺省的复制
Flask-SQLAlchemy会默认赋值,但是我们使用的时候肯定要自己起上表名的。
- 而其他的类变量则是
db.Column的实例,即表中的列名。而
db.Column的第一个参数就是列的数据类型。而在
Flask-SQLAlchemy中,原有的SQL类型对应的
Flask-SQLAlchemy列类型如下:
db.Column的其他参数大概如下,都是列的一些属性,了解SQL的应该能够直接看懂:
小技巧,类定义中可以重载一下repr函数,就我个人的习惯来说,我经常犯各种错误,而且自己找不出来,这个时候就需要动用到ide来调试,这时候重写repr函数的优势就显示出来了…….
4.2 数据库关系
通常来说,正常的SQL一般表之间会存在各式各样的关系,现在列出一个配置模型的完整的源码(sql_1.py):from flask.ext.sqlalchemy import SQLAlchemy from flask import Flask app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] ="mysql://root:@localhost/flask" app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True db = SQLAlchemy(app)
class temp1(db.Model):
__tablename__='temp1'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True)
brackref = db.relationship('temp2', backref='temp')
def __repr__(self):
return '<name %r>' % self.name
class temp2(db.Model):
__tablename__ = 'temp2'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), unique=True)
tempfk=db.Column(db.Integer, db.ForeignKey('temp1.id'))
def __repr__(self):
return '<username %r>' % self.username
上述应该比较好理解,添加给temp2一个tempfk的外键,链接的是temp1中的id列,
db.relationship()的
backref参数通过给temp2表增加
temp属性来定义反向关系。这个属性可以替代role_id访问Role模型,是作为对象而不是外键。
PS:这里我们重写了repr函数,具体的用途在之后会说的。
4.3 数据库操作
有了配置文件,我们就可以进入数据库操作部分了。这里的演示我们直接在cmd中进行,然后一边配置mysql客户端来检验。
直接调用
db.create_all()
就可以创建出数据表,
确实成功了。
另一个
db.drop_all()则是删除所有表,这里不做演示了。
下面是插入数据
但是执行完上述语句之后还没有将数据写入Mysql
只是存于Python中,而且它们对应的id值还没有分配。
修改数据库的操作由Flask-SQLAlchemy提供的db.session数据库会话来管理。准备写入到数据库中的对象必须添加到会话中:
或是更简单点的:
为了写对象到数据库,需要通过它的commit()方法来提交会话:
db.session.commit()
运行之后观察MYSQL,发现数据已经写入:
这里发现我们之前没有对id赋值但是它却有值,而且该字段是
auto_increment的,
如果我们没有显示赋值是会从0自增的,当然肯定也是可以显示赋值的。
如果要修改会话中存在的值,例如我们添加了一个
>>> from sql_1 import db,temp1,temp2 >>> test=temp1(name="1234",id=100) >>> db.session.add(test) >>> db.session.commit()
我们想把name字段改成4321
那么直接
>>> test.name="4321" >>> db.session.commit()
接下来是删除行
>>> db.session.delete(test) >>> db.session.commit()
然后是返回行
Flask-SQLAlchemy为每个模型类创建一个query对象。最基本的查询模型是返回对应的表的全部内容:
>>> from sql_1 import db,temp1,temp2 >>> temp1.query.all() [<name u'4321'>, <name u'admin'>, <name u'user'>] >>> temp2.query.all() [<username u'admin'>, <username u'user'>]
大家看看这个query.all()函数返回值是不是很眼熟,这就是我们之前在sql_1.py里面重写的repr函数的结构啊。
使用过滤器可以配置查询对象去执行更具体的数据库搜索。在表一中找出name字段为’admin’的记录。
>>> temp1.query.filter_by(name="admin").all() [<name u'admin'>]
对于给定的查询还可以检查SQLAlchemy生成的原生SQL查询,并将查询对象转换为一个字符串:
>>> str(temp1.query.filter_by(name="admin")) 'SELECT temp1.id AS temp1_id, temp1.name AS temp1_name \nFROM temp1 \nWHERE temp1.name = :name_1'
还有另外一种方式来查询,如果我们知道了用户的id,我们可以使用下面的方式查找用户信息:
>>> temp2.query.get(1) <username u'admin'>
想更深入的学习,还是看原文档吧SQLAlchemy文档
相关文章推荐
- 微软“WebDAV”提权漏洞(cve-2016-0051)初探
- 创建数据库并设置编码
- ubuntu12.04软件中心打开错误和 ubuntu 包管理之“:E: 读错误 - read (5: 输入/输出错误) E: 无法解析或打开软件包的列表或是状态文件。”的解决
- jquery获取复选框checkbox的值
- visual studio code(vscode) 调试php
- 获取图片宽高
- HDU 5642:King's Order【DP】
- ios清除缓存
- Openstack liberty install
- 初探Docker
- UIKit性能调优实战讲解
- Echarts事件
- Python shuffle() 函数
- 剑指offer-面试题6:重建二叉树
- 队列的数组实现(循环队列)
- 画图时锯齿问题
- centos 7 yum install mysql 安装mariadb 后 mysql 无法启动的解决方法
- __proto__与prototype的区别
- 一个基于SAE的一个微博爱好者证书应用
- FOXIT PDF EDITOR工具分割PDF