5.1 SQL数据库
数据库的基本概念-------------------略。
5.2 NoSQL数据库
数据库的基本概念-------------------略。
5.3 使用SQL还是NoSQL
略。
5.4 Python数据库框架
选择数据库框架时,你要考虑很多因素。
易用性、性能、可移植性、Flask集成度。
5.5 使用Flask-SQLAlchemy管理数据库
Flask-SQLAlchemy是一个Flask扩展,简化了在Flask程序中使用SQLAichemy的操作。SQLAlchemy是关系型数据库框架,支持多种数据库后台。SQLAlchemy提供了高层orm,也提供了使用数据库原生SQL的底层功能。
在Flask-SQLAlchemy中,数据库使用URL指定。
程序使用的数据库URL必须保存到flask配置对象的SQLALCHEMY_DATABASE_URI键中。配置对象中还有一个很有用的选项SQLALCHEMY_COMMIT_ON_TEARDOWN 键,将其设为 True时,每次请求结束后都会自动提交数据库中的变动。
from flask.ext.sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
db = SQLAlchemy(app)
db表示程序使用的数据库,同时还获得了Flask-SQLAlchemy提供的所有功能。
5.6 定义模型
模型表示程序使用的永久化实体。
#hello.py:定义Role和User模型
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(64), unique=True)
def __repr__(self):
return '<Role %r>' % self.name
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username=db.Column(db.String(64), unique=True,index=True)
def __repr__(self):
return '<User %r>' % self.username
类变量__tablename__定义在数据库中使用的表名。默认情况下,SQLAlchemy会有一个默认名字。其余的类变量都是该模型的属性,被定义为db.Column类的实例。
db.Column类构造函数的第一个参数是数据库列和模型属性的类型。
db.Column中其余的参数指定属性的配置选项。
5.7 关系
关系型数据库使用关系把不同表中的行联系起来。
数据库中关系的概念。------------略
5.8 数据库操作
5.8.1 创建表
db.create_all() #创建数据库
db.drop_all()#删除
5.8.2 插入行
from hello import Role, User
admin_role = Role(name='Admin')
mod_role = Role(name='Moderator')
user_role = Role(name='User')
user_john = User(username='john', role=admin_role)
user_susan = User(username='susan', role=user_role)
user_david = User(username='david', role=user_role)
模型的构造函数接受的参数是使用关键字参数指定的模型属性初始值。
在准备把对象写入数据库前,先要将其添加到会话(db.session)中。
db.session.add(admin_role)
db.session.add(mod_role)
#..........
或者:
db.session.add_all([admin_role, mod_role,...])
然后提交会话:
db.session.commit()
5.8.3 修改行
admin_role.name = 'Administrator'
db.session.add(admin_role)
db.session.commit()
5.8.4 删除行
db.session.delete(mod_role)
db.session.commit()
5.8.5 查询行
Flask-SQLAlchemy为每个模型类都提供了query对象。
#查询所有记录
Role.query.all()
User.query.all()
使用过滤器可以配置query对象进行更精准的数据库查询。
User.query.filter_by(role=user_role).all()
str(User.query.filter_by(role=user_role).all())#原生sql查询语句
5.9 在视图函数中操作数据库
#hello.py 在视图函数中操作数据库
@app.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.name.data).first()
if user is None:
user = User(username = form.name.data)
db.session.add(user)
session['known']=False
else:
session['known']=True
session['name']=form.name.data
form.name.data=''
return redirect(url_for('index'))
return render_template('index.html', form = form, name=session.get('name'), known = session.get('known', False))
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky{% endblock %}
{% block page_content%}
<div class="page-header">
<h1>Hello, {% if name %} {{ name }} {% else %} Stranger{% endif%}</h1>
{% if not known %}
<p>Pleased to meet you! </p>
{% else %}
<p> Happy to see you again! </p>
{% endif %}
</div>
{{ wtf.quick_form(form) }}
{% endblock %}
5.10 集成Python shell
每次启动 shell 会话都要导入数据库实例和模型,这真是份枯燥的工作。为了避免一直重复导入,我们可以做些配置,让 Flask-Script 的 shell 命令自动导入特定的对象。
#hello.py:为shell命令添加一个上下文
from flask.ext.script import Shell
def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role)
manager.add_command("shell", Shell(make_context=make_shell_context))
make_shell_context()函数注册了程序、数据库实例以及模型。
5.11 使用Flask-Migrate实现数据库迁移
更新表的好方法是使用数据库迁移框架。数据库迁移框架能跟踪数据库模式的变化,然后增量式的把变化应用到数据库中。
5.11.1 创建迁移仓库
首先安装Flask-Migrate,该扩展使用方法如下:
#hello.py:配置Flask-Migrate
from flask.ext.migrate import Migrate, MigrateCommand
#...
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)
为了导出数据库迁移命令, Flask-Migrate 提供了一个 MigrateCommand 类,可附加到 FlaskScript 的 manager 对象上。在这个例子中, MigrateCommand 类使用 db 命令附加。
在维护数据库迁移之前,要使用init子命令创建迁移仓库:
python hello.py db init
5.11.2 创建迁移脚本
在Alembic中,数据库迁移用迁移脚本表示。脚本中有两个函数,分别是upgrade()函数和downgrade()。upgrade()函数把迁移中的改动应用到数据库中,downgrade()函数则将改动删除。
可以用revision命令手动创建Alemic迁移,也可以用migrate命令自动创建。手动创建的迁移只是一个骨架,upgrade()和downgrade()函数都是空的,要使用Operations对象指令实现具体操作。
python hello.py db migrate -m "initial migration
5.11.3 更新数据库
检查并修正迁移脚本之后,就可以把迁移应用到数据库中:
python hello.py db upgrade