Flask python 开发篇:模型(model)Flask-SQLAlchemy的使用

19 篇文章 3 订阅

一、为什么使用模型?

上一篇分享了蓝图的使用,也说蓝图相当于了php中控制器+路由的使用,那根据MVC的经验,我们还需要一层模型(M层)

二、Flask-SQLAlchemy的引入

作为新入行的小白,用原生python去操作数据库有点为难我,所以就想到了肯定有flask的第三方库(插件)来供开发者快速使用。那我们去PyPI中去寻找合适的三方库,为什么用PyPI平台以及如何在该平台寻找需要的三方库,可以点击这里去查看

Flask-SQLAlchemy数据库中数据类型和列约束配置

Flask Python Flask-SQLAlchemy中数据库的数据类型、flask中数据可的列约束配置

三、使用Flask-SQLAlchemy构建模型文件

3.1、安装扩展

在PyPI中找到了Flask-SQLAlchemy文档,根据文档我们先看看自己环境中是否已经存在该插件,

pip show flask-SQLAlchemy

若是已经安装,则会显示该插件的基本信息,如下:
在这里插入图片描述

若是未安装,则根据文档进行安装

pip install -U Flask-SQLAlchemy
3.2、配置

安装成功以后,就是配置扩展

app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
3.3、实战使用

直接分享我的代码


from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from typing import List
from flask import jsonify

app = Flask(__name__)
#
# import os
# a=os.getenv('TEST_ENV')
# b=os.getenv('FLASK_ENV')
# print(a)
# print(1111)
# print(b)
#
# @app.route('/test111')
# def tes():
#     return '23456y7u8io'
#

app.config[
    'SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:3310/{DATABASE}?charset=utf8mb4'

db = SQLAlchemy()

db.init_app(app)


class Resource(db.Model):
    __tablename__ = 'resource'

    id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)
    r_type = db.Column(db.INTEGER, default=0, comment='resource type 0 文献 1 指南 2 大会')
    is_show = db.Column(db.INTEGER, default=0, comment='是否上架 0 未上架 1 上架')
    title = db.Column(db.String(40))
    desc = db.Column(db.TEXT)
    cover = db.Column(db.String(40))
    published_time = db.Column(db.String(40))
    content = db.Column(db.TEXT)
    file_path = db.Column(db.String(128))
    origin_link = db.Column(db.String(128))
    view_count = db.Column(db.INTEGER)
    like_count = db.Column(db.INTEGER)
    collect_count = db.Column(db.INTEGER)
    file_size = db.Column(db.String(40))
    publisher_book_name = db.Column(db.String(40))
    resource_type_id = db.Column(db.INTEGER)

    def deal_format(self):
        return {
            "id": self.id,
            "title": self.title,
            "published_time": self.published_time,
            "view_count": self.view_count,
            "publisher_book_name": self.publisher_book_name
        }


@app.route('/list')
def resource_list():

    return jsonify({
        'code': 0,
        'msg': 'success',

    })

app.run()

更多model写法可以参考文档
在这里插入图片描述

3.4、与蓝图相结合使用

我在对应的模块内(也就是跟蓝图同级别),新增了models.py文件,内容如下:

from project import testmyselfdb
from sqlalchemy.orm import Mapped, mapped_column, relationship
# from project import db

from project.extension import db

# 资源内容模型
class Resource(db.Model):
    __tablename__ = 'resource'

    id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)
    r_type = db.Column(db.INTEGER, default=0, comment='resource type 0 文献 1 指南 2 大会')
    is_show = db.Column(db.INTEGER, default=0, comment='是否上架 0 未上架 1 上架')
    title = db.Column(db.String(40))
    desc = db.Column(db.TEXT)
    cover = db.Column(db.String(40))
    published_time = db.Column(db.String(40))
    content = db.Column(db.TEXT)
    file_path = db.Column(db.String(128))
    origin_link = db.Column(db.String(128))
    view_count = db.Column(db.INTEGER)
    like_count = db.Column(db.INTEGER)
    collect_count = db.Column(db.INTEGER)
    file_size = db.Column(db.String(40))
    publisher_book_name = db.Column(db.String(40))
    resource_type_id = db.Column(db.INTEGER)

    def to_format(self):
        return {
            "id": self.id,
            "title": self.title,
            "published_time": self.published_time,
            "view_count": self.view_count,
            "publisher_book_name": self.publisher_book_name
        }

    def __repr__(self) -> str:
        return f'<Resource id={self.id} title={self.title}>'

数据库连接配置请参考这里;
前面在蓝图的使用中说到,个人认为蓝图是php中的控制器+路由的作用,那么根据以往经验,就需要在蓝图里操作数据库(MVC嘛)。参考我的蓝图代码:

3.4.1、查询数据
from flask import Blueprint, request, jsonify
from typing import List
from . import models


blog_base_blueprint = Blueprint('blog', __name__, url_prefix='/api')


# 获取所有博客文章列表
@blog_base_blueprint.route('/posts', methods=['GET'])
def get_posts():
    resource_id = request.args.get('resource_id', 10)

    resource_lists: List[models.Resource] = (models.Resource.query
                                             .filter(models.Resource.id == resource_id)
                                             .all())

    return jsonify({
        'code': 0,
        'msg': 'success',
        'data': {
            "resource_list": [resource.to_format() for resource in resource_lists]
        }
    })

3.4.2、新建数据

@blog_base_blueprint.route('/add_post', methods=['POST', 'GET'])
def create_or_update_resource():
    title = request.form.get('title')
    # json_data = request.form
    # return jsonify({
    #     'json_data' : json_data,
    #     'title' : title,
    # })

    published_time = request.args.get('published_time')
    r_type = request.args.get('r_type')

    resource = models.Resource.query.filter(models.Resource.title == title).first()

    if not resource:
        resource = models.Resource(title=title, published_time=published_time ,r_type=r_type)
        db.session.add(resource)
        db.session.commit()
        return jsonify({
            'code': 1,
            'msg': '新建成功',
            'data' : resource.to_format()
        })

3.4.3、更改数据
@blog_base_blueprint.route('/del_resource_like_log/<int:resource_id>', methods=['POST'])
def delResourceLikeLog(resource_id):
    user_id = request.form.get('user_id')
    if not user_id:
        return jsonify({
            'code': 0,
            'msg': '缺少必要用户参数',
        })
    log = models.ResourceLikeLog.query.filter_by(user_id=user_id).filter_by(resource_id=resource_id).first()

    if log:
        log.delete_flag = 1
        db.session.commit()

    return jsonify({
            'code': 1,
            'msg': '成功',
    })
3.4.3、删除数据
  • 物理删除的情况:

@blog_base_blueprint.route('/del_post/<int:resource_id>', methods=['POST', 'GET'])
def delete_resource(resource_id):

    resource = models.Resource.query.filter(models.Resource.id == resource_id).first()

    if resource:
        db.session.delete(resource)
        db.session.commit()

        return jsonify({
            'code': 1,
            'msg': '成功',
        })

    return jsonify({
            'code': 1,
            'msg': '成功',
        })


  • 逻辑删除的情况:
    其实就是软删除,我没找到像php中那样现成的软删除的方法,我是使用字段来标识,新增了一个delete_flag字段
    在这里插入图片描述

到目前为止,我所有的文件目录是这样的:

  • app.py是我项目的入口;
  • project文件夹是我所有的业务逻辑存放的地方,在project里,我又根据不同的版块创建了不同的文件夹。那些通用的逻辑比如说配置文件、扩展之类的,我放在了project的最外层,方便project下的每个模块调用。
  • ---- 在project下的blog文件夹里,我存放了跟博客(资源)相关的所有逻辑处理,包括但不限于增删改查上传。blog里又细分了C(蓝图)、M(模型)、S(服务)的逻辑文件,一目了然
    在这里插入图片描述

宣传一波:大家若是有人想北京租房可以联系我,主要是物资学院、通州北关、北苑、草房的房子。(注:我不是中介哟,我也不打算转行做中介,是我靠谱的朋友在做)
在这里插入图片描述

  • 35
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flask-SQLAlchemy 是一个用于在 Flask使用 SQLAlchemy 的工具,而 MySQL 全文检索则是 MySQL 数据库提供的一种用于进行全文搜索的技术。要在 Flask-SQLAlchemy使用 MySQL 全文检索,需要进行以下步骤: 1. 确保 MySQL 数据库版本大于或等于 5.6,并且已经启用了全文检索功能。 2. 在 Flask-SQLAlchemy 中定义需要进行全文检索的模型,并将其中需要进行全文检索的字段定义为 Text 类型。 例如,定义一个名为 `Article` 的模型,并将其中的 `content` 字段定义为 Text 类型: ```python from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class Article(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(128)) content = db.Column(db.Text) ``` 3. 创建全文索引。可以使用 SQLAlchemy 提供的 `text` 函数创建全文索引,也可以使用 MySQL 的原生语句创建全文索引。 使用 SQLAlchemy 的 `text` 函数创建全文索引的示例代码如下: ```python from sqlalchemy import text class Article(db.Model): __tablename__ = 'article' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(128)) content = db.Column(db.Text) __table_args__ = ( text('FULLTEXT idx_content (content)'), ) ``` 以上代码创建了一个名为 `idx_content` 的全文索引,该索引包含了 `content` 字段。 4. 使用全文检索进行搜索。可以使用 SQLAlchemy 提供的 `match` 函数进行全文检索,也可以使用 MySQL 的原生语句进行全文检索。 使用 SQLAlchemy 的 `match` 函数进行全文检索的示例代码如下: ```python from sqlalchemy import func articles = Article.query.filter(func.match(Article.content, 'search keyword')).all() ``` 以上代码将返回一个包含了符合搜索关键字的所有文章的列表。 使用 MySQL 的原生语句进行全文检索的示例代码如下: ```python articles = db.session.execute("SELECT * FROM article WHERE MATCH (content) AGAINST ('search keyword' IN NATURAL LANGUAGE MODE)").fetchall() ``` 以上代码使用 MySQL 的 `MATCH` 和 `AGAINST` 关键字进行全文检索,并返回一个包含了符合搜索关键字的所有文章的列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值