您的位置:首页 > 其它

Flask 框架学习(三)

2016-03-14 16:10 302 查看
( 上接Flask 框架学习(二) )

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文档
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: