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函数,这步完成后,模型的修改就能真正的映射到数据库中。

相关推荐
YJlio5 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
l1t5 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
山塘小鱼儿7 小时前
本地Ollama+Agent+LangGraph+LangSmith运行
python·langchain·ollama·langgraph·langsimth
码说AI7 小时前
python快速绘制走势图对比曲线
开发语言·python
wait_luky7 小时前
python作业3
开发语言·python
Python大数据分析@8 小时前
tkinter可以做出多复杂的界面?
python·microsoft
大黄说说8 小时前
新手选语言不再纠结:Java、Python、Go、JavaScript 四大热门语言全景对比与学习路线建议
java·python·golang
小小张说故事9 小时前
SQLAlchemy 技术入门指南
后端·python
我是章汕呐9 小时前
拆解Libvio.link爬虫:从动态页面到反爬对抗的实战解析
爬虫·python