Flask框架beginning3

1.Python操作MySQL驱动

Flask想要操作数据库,必须先安装python操作MySQL驱动。在python中,目前有以下的MySQL驱动包(建议使用mysqlclient):

mysqlclient:是目前执行最快的驱动,通过pip install mysqlclient安装,而不要在PyCharm中直接安装,可能会报错。

PyMySQL:这是一个纯Python的MySQL客户端库,但执行效率不如mysqlclient。

mysql-connector-python:这是MySQL官方提供的Python连接驱动,纯Python实现,不需要MySQL客户端库。
注意:本博客内容的所有代码基于使用mysqlclient。

2.Flask-SQLAlchemy

在Flask中,很少直接使用驱动程序(mysqlclient)来直接写原生SQL语句去操作数据库,更多的是使用SQLAIchemy提供的ORM(Object Relationship Mapping),类似于操作普通的python对象一样去实现数据库的增删改查操作。而Flask-SQLAIchemy是对SQLAIchemy的一个封装,使得在Flask中使用SQLAIchemy更加方便。Flask-SQLAIchemy需要单独安装,因为Flask-SQLAIchemy依赖于SQLAIchemy,所以只需要安装Flask-SQLAIchemy,SQLAIchemy就会自动安装。(pip install flask-aqlalchemy)SQLAIchemy类似于Jinja2,可以独立Flask被使用,可以在任何python程序中被使用。

3.Flask-SQLAlchemy的使用

连接SQL

使用Flask-SQLAlchemy操作数据库之前,需要先创建一个Flask-SQLAlchemy提供的SQLAlchemy类的对象。在创建这个类时,需要传入当前的app,然后需要在app.config中设置SQLALCHEMY_DATABASE_URI,来配置数据库的连接。

复制代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text

app = Flask(__name__)
# MySQL所在的主机名
HOSTNAME = '127.0.0.1'
# MySQL监听的端口号,默认3306
PORT=3306
# 连接MySQL的用户名
USERNAME="root"
# 连接MySQL的密码,看自己的设置
PASSWORD="1234"
# MySQL上创建的数据库名称
DATABASE="database_learn"

# 如果驱动程序时mysqlclient,那么以下前缀就是:mysql+mysqldb
# 如果驱动程序时pymysql,那么以下前缀就是:mysql+pymysql
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql://{USERNAME}:{PASSWORD}@{HOSTNAME}/{DATABASE}?charset=utf8mb4"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

db = SQLAlchemy(app)

# 测试是否连接成功的代码
with app.app_context():
    with db.engine.connect() as conn:
        result=conn.execute(text("select 1"))
        print(result.fetchall())

@app.route('/')
def hello_world():  # put application's code here
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

4.ORM模型

ORM介绍:面向对象技术映射,是一种可以使用python面向对象来操作关系型数据库的技术。具有可以映射到数据库能力的python类,称之为ORM模型。一个ORM模型与数据库中的一个表相对应,ORM模型中每一个类属性分别对应表的每个字段,ORM模型中的每一个实例对象对应表中每条数据。ORM技术提供了面向对象与SQL交互的桥梁。使用ORM模型 具有以下的优势:开发效率高、安全性高、灵活性强。

定义ORM模型,以下代码是使用Flask-SQLAlchemy来创建一个user模型。

复制代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text
from sqlalchemy.orm import DeclarativeBase
import config
from sqlalchemy.orm import DeclarativeBase,Mapped,mapped_column
from sqlalchemy import MetaData,Integer,String

# 定义命名约定的Base类
class Base(DeclarativeBase):
    metadata = MetaData(naming_convention={
        # ix:index,索引
        "ix": "ix_%(column_0_label)s",
        # uq:unique,唯一约束
        "uq": "uq_%(table_name)s_%(column_0_name)s",
        # ck:Check,检查约束
        "ck": "ck_%(table_name)s_%(column_0_name)s",
        # fk:Foreign Key,外键约束
        "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
        # pk:Primary Key,主键约束
        "pk": "pk_%(table_name)s"
    })
db = SQLAlchemy(app=app,model_class=Base)

class User(db.Model):
    __tablename__ = 'user'
    id:Mapped[int]=mapped_column(Integer,primary_key=True,autoincrement=True)
    username:Mapped[str]=mapped_column(String(50),nullable=False)
    password:Mapped[str]=mapped_column(String(100),nullable=False)

with app.app_context():
    db.create_all()

在上述的代码中,字典naming_convention是一个固定的写法,主要是用来给表约束做一些命名约束的,使得后期alembic在生成迁移脚本时,生成的约束名不是随机的,而是有命名规范的。

在User模型中,使用Mapped类型语法来让开发者和IDE识别该属性的类别,为开发提供便捷性;另外,凡是使用mapped_column创建的属性都被映射都表中成为字段,并且该字段有什么配置,并且该字段有什么配置,都可以在mapped_column中添加相关参数。

之后,调用db.create_all()方法,就会将该模型迁移到数据库中生成一张表,这种方式在字段中发生改变时无法自动同步到数据库中,所以仅作为一种临时解决方案,后续会使用flask-migrate来实现。

常用的属性和参数

在上述user模型中,db.Integer和db.String,除了这两种模型,还有以下的模型:

字段类型 描述 对应MySQL类型 示例
Integer 整数类型 INT id = Column(Integer)
String 字符串类型 VARCHAR name = Column(String(50))
Text 长文本类型 TEXT content = Column(Text)
Boolean 布尔类型 TINYINT(1) is_active = Column(Boolean)
Float 浮点数类型 FLOAT price = Column(Float)
Double 双精度浮点数 DOUBLE rating = Column(Double)
Numeric/Decimal 定点数 DECIMAL amount = Column(Numeric(10, 2))
DateTime 日期时间 DATETIME created_at = Column(DateTime)
Date 日期 DATE birthday = Column(Date)
Time 时间 TIME start_time = Column(Time)
Enum 枚举类型 ENUM status = Column(Enum('active', 'inactive'))
JSON JSON类型 JSON data = Column(JSON)
LargeBinary 二进制数据 BLOB image = Column(LargeBinary)
PickleType Python对象序列化 BLOB config = Column(PickleType)
参数名 描述 默认值 示例
primary_key 设置为主键 False id = Column(Integer, primary_key=True)
autoincrement 自增 True(主键时) id = Column(Integer, autoincrement=True)
nullable 是否允许NULL True name = Column(String, nullable=False)
unique 是否唯一 False email = Column(String, unique=True)
default 默认值 None created_at = Column(DateTime, default=datetime.now)
server_default 数据库端默认值 None status = Column(String, server_default='active')
onupdate 更新时的值 None updated_at = Column(DateTime, onupdate=datetime.now)
index 创建索引 False username = Column(String, index=True)
comment 字段注释 None Column(String, comment='用户姓名')
name 数据库列名 属性名 Column('user_name', String(50))
key Python属性名 None Column('db_name', String, key='name')

5.模型迁移

Flask-Migrate介绍

定义好模型后,是通过db.create_all()的形式将ORM模型映射到数据库中,这种形式比较局限,只能识别到新增了模型后映射到数据库中,对于模型中数据的修改、类型的修改无法识别。因此,在实际开发中,都不会使用db.create_all()来做ORM模型迁移,而是借助一个第三方库Flask-Migrate来实现。Flask-Migrate数据alembic来实现的,alembic是专门用来做SQLAlchemy的ORM模型做迁移的。要使用Flask-Migrate,先通过pip安装Flask-Migrate。

pip install flask-migrate==4.1.0,alembic会随着flask-migrate的安装而安装。

创建迁移对象

使用Flask-Migrate创建迁移对象,需要通过类Migrate来实现。

初始化迁移环境

在创建完迁移对象后,需要初始化一下迁移环境。方法是在当前的根目录下执行以下的命令:

flask db init

执行完命令后,会在根路径下生成一个migrations文件夹,该文件夹下有以下文件:

versions:文件夹,用于后面生成的迁移脚本文件。

alembic.ini:alembic的配置文件。

env.py:配合flask项目迁进行移的的python文件。

script.py.mako:生成迁移脚本的模板文件。
注意:次工作只需要初始化一遍,无需重复初始化。

生成迁移脚本

在初始化完成迁移环境的前提下,无论是新增ORM模型,还是ORM模型中有任何字段信息发生改变,并且想要将这些改变同步到数据库中,那么就需要进行修改,生成一个迁移脚本,生成迁移脚本命令如下:

flask db migrate -m "备注信息"

以上命令,-m后跟着的是备注信息,方便以后查看当前迁移脚本做了哪些事情。备注信息不是强制的,如果不想添加,可将-m及以后的命令删除。在执行完以上的命令后,version文件夹会新增一个python脚本文件。

执行迁移脚本

生成迁移脚本完成后,需要执行迁移脚本,才能把这些改变真正同步到数据库中。执行迁移脚本命令如下:

flask db upgrade

上述命令会自动从version文件夹中寻找最新的迁移脚本文件,然后执行迁移脚本文件中的upgrade函数,这步完成后,模型的修改就能真正的映射到数据库中。

相关推荐
lancyu10 小时前
关于多轮对话机器人的上下文Token优化和解决方案
人工智能·python·深度学习·机器学习·chatgpt·机器人·prompt
草莓橙子碗10 小时前
Claude 使用指南
开发语言·python
工具分享11 小时前
陪跑跟品爆单AI选品助手,高效跟品会赔本吗?
人工智能·python
COOLMO研究AI11 小时前
Python 如何实现 AI API 的提示词(Prompt)版本管理与热更新
人工智能·python·prompt
老郑聊AI业财智造11 小时前
Transformer 技术架构与源码分析
人工智能·python·深度学习·语言模型·架构·transformer·软件工程
程序员三藏11 小时前
自动化测试用例编写详解
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
230万光年的思念12 小时前
分子动力学模拟参考文献
python
HongXu_CaiYi12 小时前
0103-python相关-函数、文件
python
vortex513 小时前
从Conda到UV:Python项目依赖管理的现代演进
python·conda·uv
何以解忧,唯有..14 小时前
Python time 模块详解:时间处理与日期操作指南
开发语言·python