NoSQL从零开始用 Flask 搭建筑一个网站(二)

从零开始用 Flask
搭建筑一个网站(一)
介绍了哪些搭建 Python 环境,以及 Flask
应用为主项目布局。我们要搭建的网站是管理第三方并的控制台,类似于
Slack。 本篇主要讲解数据如何在 Flask
应用中流淌,其它的框架基本上也是各有千秋。

数据库

既是是数量的流,首先要确立于存取数据的地方,也尽管是数据库了(这里是依涉嫌项目数据库,NoSQL
不以当时讨论)。第一节被我们采取了 Flask-SQLAlchemy 管理数据库,在
Flask-SQLAlchemy 中,数据库使用 URL 指定,最盛行的数据库 URL 格式如下:

数据库引擎 URL
MySQL mysql://username:password@hostname/database
Postgres postgresql://username:password@hostname/database
SQLite(Unix) sqlite:////absolute/path/to/database
SQLite(Windows) sqlite:///c:/absolute/path/to/database

每当 config.py 中我们早就指定了数据库
URL,如果运用云平台部署程序,直接用转变的数据库 URL 写到 config.py 中
SQLALCHEMY_DATABASE_URI 即可。这里我们应用的凡 SQLite
数据库。Flask-SQLAlchemy
采用数据库抽象层来操作数据库,也称之为对象关联映射(Object-Relational
Mapper,
ORM),在用户不知不觉的景下将高层的面向对象操作转换成为低层的数据库指令,因此易用性好。我们既在
app/__init__.py 中实例化了 SQLAlchemy 类:

app/__init__.py

from flask_sqlalchemy import SQLAlchemy
...
db = SQLAlchemy()
...
概念模型

范类可以掌握为数据库被之同摆放表,Flask-SQLAlchemy
提供了一个基类和平等密密麻麻辅助类和函数来叫咱定义模型的组织。我们直接在 app
文件夹下开创一个 models.py
文件。鉴于每个网站要求都非同等,所抱的多寡吧殊,但本质上是相差无几的。这里以作者网站要求吗条例,需要创造
Developer,Integration 和 Channel 三独说明。

app/models.py 部分代码

from flask import current_app
from app import db

class Developer(db.Model):    
    __tablename__ = 'developers'    
    id = db.Column(db.Integer, primary_key=True)    
    dev_key = db.Column(db.String(40), unique=True, index=True)    
    platform = db.Column(db.String(50))    
    platform_id = db.Column(db.String(40), unique=True)    
    username = db.Column(db.String(150), index=True)    
    integrations = db.relationship('Integration', backref='developer')    
    channels = db.relationship('Channel', backref='developer')

class Integration(db.Model):    
    __tablename__ = 'integrations'    
    id = db.Column(db.Integer, primary_key=True)    
    integration_id = db.Column(db.String(40), unique=True)    
    name = db.Column(db.String(100))    
    description = db.Column(db.String(150))    
    icon = db.Column(db.String(150))    
    channel = db.Column(db.String(150))    
    token = db.Column(db.String(150))    
    developer_id = db.Column(db.Integer, db.ForeignKey('developers.id'))

class Channel(db.Model):    
    __tablename__ = 'channels'    
    id = db.Column(db.Integer, primary_key=True)    
    developer_id = db.Column(db.Integer, db.ForeignKey('developers.id'))    
    channel = db.Column(db.String(150))    

    def __repr__(self):        
        return '<Channel %r>' % self.channel

方的每个 Class 都延续了 Model
类,因此每个接近在数据库被还体现吗平布置表,表名用 __tablename__
表示,一般用复数形式。这里要谈一下有大抵的关系。可以看地方 Developer
和 Integration 及 Channel
都发生一个一对多的干,一个用户可发差不多个集成和多单频道。 看到这半句子:

integrations = db.relationship('Integration', backref='developer')
developer_id = db.Column(db.Integer, db.ForeignKey('developers.id'))

首先句表明添加到 Developer 表的 integrations
属性表示此涉及的面向对象视角,对于一个 Developer 实例,integrations
属性将回来跟 Developer 相关的富有 Integration,db.relationship()
第一只参数表明关系之别一样端是哪位模型,backref 参数为 Integration
添加一个 developer 属性,从而定义反朝关系。第二句是于 Integration
表中创造一个 developer_id
字段,这个字段被定义为外键,就是这外键建立由了关系。传于
db.ForeignKey() 的参数 ‘developers.id’ 表明这列的值是 developers
表中行的 id 值。另外,__repr__()
方法返回一个具备可读性的字符串表示模型,可以在调节和测试时采用。下面我们就是当命令行中操作一下数据库。
先是实施:

//创建 migrations 文件夹及相关文件
python manage.py db init

接下来实施 :

//自动创建迁移脚本
python manage.py db migrate
//创建数据表或者升级到最新版本
python manage.py db upgrade

而后模型类产生改变,比如去或补充加列,都如实行这片单令,更新数据库表。现在于列目录下该自动生成了名叫也
dev 的数据库。
连下去执行如下命令进入 Python Shell:

python manage.py shell
创建表

使用 db.create_all() 就得因模型类创建表。如图:

NoSQL 1

使用 db.drop_all()
方法就可以去所有的申,但是这种办法较粗,所有的数码为联合销毁了。

插入行

以下命令于数据库表中插入了千篇一律条数:

NoSQL 2

透过数据库会话 db.session
来管理针对数据库所开的反,在备选把目标写副数据库之前,首先要补加到会话中,然后据此
commit() 方法提交会话。接下来我们累插入一条 Integration 数据:

>>>from app.models import Integration,Channel
>>>integration = Integration(integration_id='i0001',name='github',description='first >>>application',channel='github_event',developer=developer)
>>> db.session.add(integration)
>>> db.session.commit()

只顾点的 developer 属性,正是我们在 models.py 中 Developer
模型中定义之同一对准多关系 integrations 属性的 backref 值,
所谓的反向关系就是借助以 Integration 表中每条数还起一个 developer 属性指向
Developer 表中之某条数据,这是同等对大多涉及的高等代表。现在得以就此
developer.integrations 来查看该 developer 拥有的什么样集成,运行截图如下:

NoSQL 3

修改行

每当付给数据库会话之前,改变目标的之一属性然后还提交即可更新行数据。如:

>>> developer.username = 'lisi'
>>> db.session.add(developer)
>>> db.session.commit()

运行截图:
NoSQL 4

删除行

调用 db.session.delete() 方法即可删除行:

>>>db.session.delete(developer)
>>>db.session.commit()
查询行

Flask-SQLAlchemy 为每个模型提供了 query
对象,最基本的查询是回到表中的具备记录:

>>>Developer.query.all()

运过滤器可以进行再次准确的询问:

>>>Developer.query.filter_by(platform='qq').all()

要是您退了 shell 会话,前面创建的对象就是非会见因 Python
对象的样式有,而是作为各自数据库表中的推行。这时急需重数据库被读取行,再重复创设
Python 对象,如:

>>> new_developer = Developer.query.filter_by(dev_key=12345).first()

小心点的 first() 方法,如果未丰富,将回来一个 BaseQuery
对象,这样就非能够一直用 new_developer 来访问它的属性值。

每当视图函数中操作数据库

方介绍的兼具数据库操作可以一直当视图函数中开展。假设我们只要召开一个简陋的报功能,下面我们便来看望哪自网页遭到获取数据并保存在数据库被。我们先定义一个用户模型:

app/models.py

class User(db.model):
    __tablename__ = 'users'
    id = db.column(db.Integer, primary_key=True)
    username = db.column(db.String(50), unique=True)
    password = db.column(db.String(100))

    def __repr__(self):
        return '<User %r>'  % self.username

接下来于 main 文件夹下创造一个 forms.py 文件。

app/main/forms.py

from flask_wtf import Form
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequired

class UserForm(Form):      
    username = StringField('Input your username', validators=[DataRequired()])    
    password = PasswordField('Input your password', validators=[DataRequired()])    
    submit = SubmitField('Submit')

咱们采用了 flask-wtf 扩展(pip install flask-wtf)来处理表单。
然后我们之所以当 index 页面中显示是表单。

index.html

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}注册{% endblock %}

{% block content %}
    {% for message in get_flashed_messages() %}    
        <div class="alert alert-warning">        
            <button type="button" class="close" data-dismiss="alert">×</button>        
            {{ message }}    
        </div>
    {% endfor %}
    <div id="form">
        <div class="col-md-4">
            {{ wtf.quick_form(form) }}
        </div>
    </div>
{% endblock %}

今昔回到 views.py 中,在咱们的视图函数中犯如下改变:

app/main/views.py

...
from .forms import UserForm
from ..models import User
from app import db


@main.route('/', methods=['GET', 'POST'])
def signin():
    form = UserForm()
    if form is None:
        flash('Should input username and password')
    elif  form.validate_on_submit():
        user = User(username=form.username.data, password=form.password.data)
        db.session.add(user)
        try:
            db.session.commit()
            flash('User created !')
        except:
            db.session.rollback()
            flash('User create failed')
    return render_template('index.html', form=form)

通下我们运行一下此有点试验:

python manage.py runserver

总结

本节咱们介绍了在 Flask 中凡是怎么下 Flask-SQLAlchemy
、Flask-Migrate来管理数据库,并且示范了数码从网页储存到数据库的经过,这只是是最最基础的片段,下一致节约咱们用探索如何在网页上发送请求又赢得数码,以及怎样以页面中传递数据。

作者:KenChoi – 极光
原文:从零开始用 Flask
搭建筑一个网站(二)
知乎专栏:极光日报

网站地图xml地图