Flask 框架学习(三)

( 上接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如下:

Flask 框架学习(三)_第1张图片

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列类型如下:

Flask 框架学习(三)_第2张图片

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客户端来检验。

Flask 框架学习(三)_第3张图片

直接调用

db.create_all()

就可以创建出数据表,

确实成功了。
另一个db.drop_all()则是删除所有表,这里不做演示了。

下面是插入数据

这里写图片描述

但是执行完上述语句之后还没有将数据写入Mysql

这里写图片描述

只是存于Python中,而且它们对应的id值还没有分配。
修改数据库的操作由Flask-SQLAlchemy提供的db.session数据库会话来管理。准备写入到数据库中的对象必须添加到会话中:

这里写图片描述

或是更简单点的:

这里写图片描述

为了写对象到数据库,需要通过它的commit()方法来提交会话:

db.session.commit()

运行之后观察MYSQL,发现数据已经写入:

Flask 框架学习(三)_第4张图片

这里发现我们之前没有对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文档

你可能感兴趣的:(数据库,mysql,python,sqlalchemy,flask框架)