07-数据表创建方式(Database First、Model First、Code First)

常见的创建数据表结构的三种方式:

  • Database First
  • Model First   DBA经常使用这个方式
  • Code First    推荐程序员使用, 此方法专注于业务模型的设计,而不是专注数据库设计

 

Flask-SQLAlchemy介绍
SQLALchemy 实际上是对数据库的抽象,让开发者不用直接和 SQL 语句打交道,而是通过 Python 对象来操作数据库,在舍弃一些性能开销的同时,换来的是开发效率的较大提升
SQLAlchemy是一个关系型数据库框架,flask-sqlalchemy 是一个简化了 SQLAlchemy 操作的 flask 扩展。

1) 安装 flask-sqlalchemy

pip install flask-sqlalchemy

2) 通过Code First,创建数据表的简单示例

from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String

# 实例化 Flask 对象
app = Flask(__name__)

# 配置数据库连接信息
app.config['SQLALCHEMY_DATABASE_URI'] =  'mysql://root:tyy19950225@localhost:3306/fisher'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 实例化 SQLAlchemy
db = SQLAlchemy(app)

# 定义数据库模型
class Book(db.Model):
    __tablename__ = 'book'

    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(50), nullable=False)
    author = Column(String(30), default="未名")
    binding = Column(String(20))
    publisher = Column(String(50))
    price = Column(String(20))
    pages = Column(String(20))
    pubdate = Column(String(20))
    isbn = Column(String(15), nullable=False, unique=True)
    summary = Column(String(1000))
    image = Column(String(50))

# 创建所有数据库表
with app.app_context():
    db.create_all()

# 示例路由:查询所有书籍
@app.route('/book/', methods=['GET'])
def get_books():
    # 查询数据库中的所有书籍
    books = Book.query.all()
    book_list = [{'title': book.title, 'author': book.author} for book in books]
    return jsonify(book_list)

# 应用入口
if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000, debug=True)

 

扩展:数据库完整连接 URI 列表(Flask学习(4)——数据库_db.creatall-CSDN博客

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

hostname:数据库服务所在的主机

database:要使用的数据库名

username:数据库用户名

password:数据库密码

 

优化蓝图实战(图书数据搜索与查询),实现将模型映射到数据库

项目结构

配置文件 app/secure.py

# 配置参数
DEBUG = False

# 配置数据库链接
# mysql数据库,数据库驱动cymysql
# SQLALCHEMY_DATABASE_URI = 'mysql+cymysql://root:tyy19950225@localhost:3306/fisher'
SQLALCHEMY_DATABASE_URI = 'mysql://root:tyy19950225@localhost:3306/fisher'

入口文件 fisher2.py

from flask import Flask, make_response, jsonify
from datetime import datetime
from app import create_app

# 创建flask对象
app = create_app()


if __name__ == '__main__':

    app.run(host= '0.0.0.0', debug=app.config['DEBUG'], port=5000)

视图函数,校验文件 app/form/book.py

# 使用WTForms验证用户输入参数的有效性

from wtforms import Form, StringField, validators

class searchForm(Form):
    # 校验规则,参数不能为空、验证用户输入的字符串长度在1到30之间、
    q = StringField(validators=[
        validators.DataRequired(message="参数不能为空"),
        validators.Length(min=1, max=30)])

 

1) 创建蓝图

初始化 app/web/__init__.py

# 蓝图 blueprint 蓝本
from flask import Blueprint

web = Blueprint('web', __name__)

from app.web import book

指定路由和视图函数 app/web/book.py

from flask import jsonify, request
from multidict import MultiDict

from app.libs.httper import HTTP
from . import web
from ..forms.book import searchForm

# # 蓝图 blueprint 蓝本
# web = Blueprint('web', __name__)

# 关键字搜索:http://t.talelin.com/v2/book/search?q={}&start={}&count={}
# isbn搜索: http://t.talelin.com/v2/book/isbn/{isbn}
ISBN_URL = "http://t.talelin.com/v2/book/isbn/{}"
KEY_URL = "http://t.talelin.com/v2/book/search?q={}&start={}&count={}"

# get请求
@web.route('/book/getSearch/', methods=['GET'])
def getSearch():
    print("========正在获取get请求=========")

    # # 从请求参数中获取 q
    # q = request.args.get('q')
    # print("参数q:", q)

    # 校验
    form = searchForm(request.args)
    if form.validate():
        # 从请求参数中获取 q (从form中取数,能够更好的验证)
        q = form.q.data
        # strip() 方法用于移除字符串头尾的空白字符或指定字符序列
        q = q.strip()

        # 调用search_book_data方法,获取图书数据
        result = search_book_data(q)

        return jsonify(result), 200
    else:
        return jsonify(form.errors), 400


# post请求
@web.route('/book/postSearch/', methods=['POST'])
def postSearch():
    print("========正在获取post请求=========")

    # # 从请求参数中获取 q
    # # 首先获取 JSON 请求体
    # data = request.get_json()
    # # 然后再从请求体中提取参数
    # q = data.get('q')
    # print("参数q:", q)

    # 校验
    # 首先获取 JSON 请求体
    data = request.get_json()
    # 将 JSON 字典转换为 MultiDict
    form_data = MultiDict(data)
    form = searchForm(form_data)
    if form.validate():
        # 从请求参数中获取 q (从form中取数,能够更好的验证)
        q = form.q.data
        # strip() 方法用于移除字符串头尾的空白字符或指定字符序列
        q = q.strip()

        # 调用search_book_data方法,获取图书数据
        result = search_book_data(q)

        return jsonify(result), 200
    else:
        return jsonify(form.errors), 400

def search_book_data(q):
    # 调用is_isbn_or_key方法,判断q是关键字还是isbn
    isbn_or_key = is_isbn_or_key(q)

    # 根据isbn_or_key的值,获取相应的url
    if isbn_or_key == "isbn":
        url = ISBN_URL.format(q)
        print("进入isbn查询,url:", url)
        result = HTTP.get(url)
    else:
        url = KEY_URL.format(q, 1, 5)
        print("进入关键字查询,url:", url)
        result = HTTP.get(url)

    return result


def is_isbn_or_key(q):
    # 默认q为关键字
    isbn_or_key = "key"

    # 判断q是否为isbn
    # isbn13 是由13位0到9数字组成的字符串
    # isbn10 是由10位0到9数字组成,含有一些 "-"
    if q.isdigit() and len(q) == 13:
        isbn_or_key = "isbn"

    short_q = q.replace("-", "")
    if q.isdigit() and len(short_q) == 10 and q in "-":
        isbn_or_key = "isbn"

    return isbn_or_key

视图函数文件 libs/httper.py

import requests

class HTTP:
    # 发送GET请求
    @staticmethod
    def get(url, return_json=True):
        response = requests.get(url)
        if response.status_code == 200:
            if return_json:
                return response.json()
            else:
                return response.text
        else:
            print(f"Error: {response.status_code}")
            return None

    # 发送POST请求
    @staticmethod
    def post(url, data, headers={}, return_json=True):
        response = requests.post(url, data=data, headers=headers)
        if response.status_code == 200:
            if return_json:
                return response.json()
            else:
                return response.text
        else:
            print(f"Error: {response.status_code}")
            return None

 

2) 注册蓝图,在初始化中实例化flask对象,并注册蓝图

初始化 app/__init__.py

from flask import Flask
from app.web import web
from app.models.book import db

def create_app():
    # 实例化flask对象
    app = Flask(__name__)
    # flask对象加载配置文件
    # app.config.from_object('config')
    app.config.from_object('app.secure')

    # 调用注册蓝图的方法
    register_blueprint(app)

    # 初始化数据库
    with app.app_context():
        db.init_app(app)
        db.create_all()

    return app

def register_blueprint(app):
    # 注册蓝图
    app.register_blueprint(web)

 

3)  实例化SQLAlchemy对象,并创建Book实体类(模型映射到数据库)

from sqlalchemy import Column
from sqlalchemy import Integer, String, Float, Text, DateTime, Boolean, ForeignKey, Table
from flask_sqlalchemy import SQLAlchemy

# 实例化SQLAlchemy对象
db = SQLAlchemy()

class Book(db.Model):
    __tablename__ = 'book'

    # id属性,整型,主键,自动增长
    id = Column(Integer, primary_key=True, autoincrement=True)
    # title属性,字符串类型,不允许为空
    title = Column(String(50), nullable=False)
    author = Column(String(30), default="未名")
    binding = Column(String(20))
    publisher = Column(String(50))
    price = Column(String(20))
    pages = Column(String(20))
    pubdate = Column(String(20))
    isbn = Column(String(15), nullable=False, unique=True)
    summary = Column(String(1000))
    image = Column(String(50))

    def sample(self):
        pass

posted @ 2024-10-11 18:23  马铃薯1  阅读(67)  评论(0编辑  收藏  举报