FLASK数据库模型

共 6029字,需浏览 13分钟

 ·

2020-10-15 23:00

点击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

云想衣裳花想容,春风拂槛露华浓。

SQLAlchemy 是一个基于 Python 实现的 ORM 库,是一种 面对对象 的数据库编程框架 (关系对象映射)。


快速入门文档

http://www.pythondoc.com/flask-sqlalchemy/quickstart.html


安装


pip install sqlalchemy


在 Flask 项目中的 URI 配置


class Config:
    SECRET_KEY ="abc_caonima_wocao" # 随机 SECRET_KEY
    SQLALCHEMY_COMMIT_ON_TEARDOWN = True # 自动提交
    SQLALCHEMY_TRACK_MODIFICATIONS = True # 自动sql

    DEBUG = True # debug模式
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://%s:%s@%s:%s/%s' % (DB_USERNAME, DB_PASSWORD,DB_HOST, DB_PORT, DB_NAME) #数据库URL


在初始化项目中连接


app = Flask(__name__,template_folder='templates',static_folder='static')
app.config.from_object(Config)

db = SQLAlchemy(app)
db.init_app(app)


这样就把 数据库Flask实例联系起来了,这里使用 Mysql


建立数据库模型


所谓数据库模型,说白了就是建立数据库中所需的具体字段,包括字段名称,类型,限制条件等等


比如在个人博客中,我们需要有文章列表,也需要有文章详情的数据库模型。


编写模型对象

class Article(db.Model):
        __tablename__ = 'article'
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(db.String(32))
        author = db.Column(db.String(32))
        img_url = db.Column(db.Text, nullable=False)
        content = db.Column(db.Text, nullable=False)
        tag = db.Column(db.String(64), nullable=True)
        uuid = db.Column(db.Text, nullable=False)
        create_time = db.Column(db.DateTime, nullable=True, default=datetime.now)
        uid = db.relationship('Article_Detail', backref='article')

        def __repr__(self):
            return '' % self.title


这样就实现了文章的数据库所需字段

id:数据库id,主键

title:文章标题,字符类型,后面声明长度

author:作者,字符类型

img_url:图片,text类型

content:文章简介

tag:所属标签

uuid:文章唯一标识id

create_time:创建时间,detatime类型

uid反向代理,通过关联的名称表可以得到 article表中的属性


Article_Detail模型

class Article_Detail(db.Model):
    __tablename__ = 'article_detail'
    id = db.Column(db.Integer, primary_key=True)
    d_content=db.Column(db.Text,nullable=False)
    uid = db.Column(db.Integer, db.ForeignKey('article.id'))

    def __repr__(self):
        return '' % self.title


id:数据库id,主键

d_content:详情文章内容,文本类型

uid外键,关联到 article 表 id


通过 relationship ForeignKey 把文章和文章详情表联系起来,在编写文章详情的时候,通过 uid 选择是哪一篇文章的详情即可。


对于个人博客而言,模型的关联并没有很复杂,一般是 一对多 的操作就可以搞定,当然如果是论坛或者社区的话,会用到 多对一多对多 的数据库操作 ,不做详细介绍。


增删改查


SQLAlchemy  之所以这么流行,在 Flask 中地位如此之高,基于它是面对对象的数据库编程。


所以,对于数据查询,添加等操作也是非常的简单。


查询文章列表:

@home.route('/')
def index():
    init_list= Article.query.order_by(db.desc(Article.create_time)).all()
    return render_template('home/index.html', datas=init_list)


可以看到,查询所有文章的语句,这里是按照创建的时间排序的,注意到desc(Article.create_time),然后将所得列表传给前端页面,渲染完成。


再来看看根据 id 查询文章详情内容的路由实现:

@home.route('/article/')
def query_detail(uuid):
    base_path = os.path.abspath('app/templates/article/')
    old_file = os.listdir(base_path)[0]
    old_path = os.path.join(base_path, old_file)
    file_path = os.path.abspath('app/templates/article/{}.html'.format(uuid))
    if not os.path.exists(file_path):
        log_v.debug("[-] File does not exist, renaming !!!")
        os.rename(old_path, file_path)
    form = CommentForm()
    searchForm = SearchForm()
    article_res = Article.query.filter_by(uuid=uuid).first()
    article_detail_res = Article_Detail.query.filter_by(uid=article_res.id).first()
    return render_template('article/{}.html'.format(uuid), a_data=article_res, d_data=article_detail_res, form=form,
                           searchForm=searchForm)



思路设计:

    在templates模板目录中新建一个article 用于存放文章详情页的html文件,并且索引到这个目录中,在这个目录中只有一个 html 文件,我们只需要向这个html文件填入查询回来的数据即可。


    由于文章列表需要根据文章的 uuid 来跳转到详情页,所以这个 html文件的名称需要 rename 为跳转文章的 uuid,才能正确跳转。


    最后,根据 uuid 查询到文章,再由文章的 id 查询到详情文章内容,渲染到详情页。


是不是及其简单,所以前期的工作主要是数据库模型字段的设计,还有迁移到数据库中,也就是创建表,让其工作。


数据库迁移


使用 flask_migrate 扩展可以非常简单的进行数据库的迁移


# coding:utf8
from datetime import datetime
from flask_migrate import Migrate, MigrateCommand
from app import app
from app.models import db
from flask_script import Manager, Server

manage = Manager(app)

# 迁移
Migrate(app,db)
manage.add_command('db',MigrateCommand)

if __name__ == "__main__":
    manage.run()

'''
初始化
python manage.py db init

创建迁移
python manage.py db migrate

执行迁移
python manage.py db upgrade
'''


黑窗口  执行命令  python manage.py db init 


初始化数据库,执行之后会在主 app 目录中生成一个 migrations 目录,里面包含了一些创建的信息,如 版本号操作脚本


然后执行  python manage.py db migrate

迁移数据库,在数据库中真正创建表字段


最后执行  python manage.py db upgrade  让其生效


PS:在往后的每一次更改数据库模型中的字段之后,只需要执行后两个命令即可。


关于数据库回滚


# -*- coding:utf-8 -*-
import os
from datetime import datetime
from sqlalchemy import or_
from app import app,db
from app.Logger.logger import log_v
from app.forms import CommentForm, SearchForm
from app.tools.getIdAddr import getAddr
from app.home.home import home
from flask import render_template, request, redirect
from app.models import Article, Article_Detail, Global_V, Comment,UserIP


@home.route('/postComment/', methods=['GET', 'POST'])
def postComment(uuid):
    # app.config.update(SECRET_KEY=os.urandom(24))
    # log_v.debug("[*] UPDATE SECRET_KEY")
    log_v.debug("[+] Add Comment")

    form = CommentForm()
    # 字段必须完整
    if request.method == "POST" and form.validate_on_submit():
        theme = form.theme.data
        content = form.content.data
        email = form.email.data
        csrf_token = form.csrf_token.data
        t_md = request.form.get("t_md","")
        if all([theme, email, content, csrf_token, t_md]):
            try:
                add_comment = Comment(theme=theme, email=email, content=content, uuid=uuid)
                db.session.add(add_comment)
                db.session.commit()
                return "评论成功"
            except Exception as e:
                db.session.rollback()
                return "评论失败"

            finally:
                log_v.debug("Comment Done   " + theme + ' ' + ' ' + content + ' ' + email + ' ' + t_md)

        else:
            return "参数不齐"
    else:
        return redirect('/article/{}'.format(uuid))


数据库的回滚是十分有必要的,用于处理程序或者数据错误,让程序回到上一次的状态,这就是所谓的数据库回滚,否则很可能会造成死锁或者超时,这是非常可怕的。


所以,请回滚!!!

------------------- End -------------------

往期精彩文章推荐:

欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持

想加入Python学习群请在后台回复【入群

万水千山总是情,点个【在看】行不行

/今日留言主题/

随便说一两句吧~~

浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报