Flask-SQLAlchemy flask-migrate mysql用法记录

发布时间 2023-11-28 11:15:59作者: PKGAME

一、简介

二、内容

三、问题

 

一、简介

  • Flask-SQLAlchemy 是一个为 Flask 应用增加 SQLAlchemy 支持的扩展。它致力于简化在 Flask 中 SQLAlchemy 的使用。
  • SQLAlchemy 是目前python中最强大的 ORM框架, 功能全面, 使用简单。
ORM优缺点
优点

有语法提示, 省去自己拼写SQL,保证SQL语法的正确性
orm提供方言功能(dialect, 可以转换为多种数据库的语法), 减少学习成本
防止sql注入攻击
搭配数据迁移, 更新数据库方便
面向对象, 可读性强, 开发效率高
缺点

需要语法转换, 效率比原生sql低
复杂的查询往往语法比较复杂 (可以使用原生sql替换)

 

  flask-migrate

在实际的系统开发中,经常碰到需要更新数据库中的表或修改字段等操作。
如果通过手工编写SQL脚本进行处理,修改起来就会非常麻烦。
Flask-Migrate数据库迁移框架就是专门解决这个问题的。
使用Flask-Migrate数据库迁移框架可以保证数据库结构在发生变化时,改变数据库结构不至于丢失数据库的数据。

 

二、内容

  1 安装

  1.1 命令安装

pip3 install flask-sqlalchemy

pip3 install flask-migrate

  

  2.1 使用

  2.1.1 安装数据库驱动

    我这里使用的mysql 数据库,所以使用flask-sqlalchemy, 还得装一个驱动

pip3 install pymysql

  2.1.2 在python项目文件里 flask 配置连接数据库

   # MySQL所在主机名
    HOSTNAME = "127.0.0.1"
    # MySQL监听的端口号,默认3306
    PORT = 3306
    # 连接MySQL的用户名,自己设置
    USERNAME = "root"
    # 连接MySQL的密码,自己设置
    PASSWORD = "123456"
    # MySQL上创建的数据库名称
    DATABASE = "test2"
    # 通过修改以下代码来操作不同的SQL比写原生SQL简单很多 --》通过ORM可以实现从底层更改使用的SQL
    # SQLALCHEMY_DATABASE_URI= f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
    SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}"

  2.1.3 创建flask实例对象,并导入配置

    flask_app = Flask(__name__)

    # 导入配置项目
    flask_app.config.from_object(config[config_name])

  2.1.4 创建flask-sqlalchemy 对象并加载进flask

   db = SQLAlchemy()
    db.init_app(flask_app)

  2.1.5 定义一个测试模型类, 注意这个类必须再上一步之后,在不同文件包之间导入时要注意

class Role(db.Model):
   __tablename__= 'roles' 
   id = db.Column(db.Integer, primary_key=True)
   name = db.Column(db.String(64), unique=True)
   def _repr_(self):
      return '<Role %r>' % self.name

  2.1.6当定义模型好了后,就需要运行去数据库创建表

     我这里使用的是 flask cli  插件。

@app.cli.command("create_table")
def say_hello():
    from application import db
    # 创建表
    db.create_all()
    print('处理完成')

  2.1.7 声明flask变量

    要使用这个,就得先在环境中声明flask 命令

linux

$ export FLASK_APP=app
$ flask run

windows

> set FLASK_APP=app
> flask run

windows powershell

> $env:FLASK_APP="app"
> flask run

   如果不声明,有可能找不到flask 命令

   其中 参数的意思,  有不懂的可以参考这里: 去看看

FLASK_APP=src/app
设置src为当前工作目录,并导入app.py

FLASK_APP=app:app2
使用app.py中的app2实例

FLASK_APP=app:create_app('dev')
使用app.py中的工厂函数create_app并传入参数dev

    测试下效果

@app.cli.command("hello")
def say_hello():
    click.echo("Hello World!")

    2.1.8然后你可以使用类似的方式去创建数据表

@app.cli.command("create_table")
def create_table():
    from application import db
    # 创建表
    db.create_all()
    print('处理完成')

@app.cli.command("drop_table")
def drop_table():
    from application import db
    # 只删除有的模型表
    db.drop_all()
    print('处理完成')

    但是,这个有个缺点,就是模型有变化,flask-sqlalchemy 不能同步数据库的字段变化,他的主要作用还是在模型的操作上,这个flask-migrate就可以解决,这里只是方便展示用。

    试试 添加数据

@app.cli.command("add_data")
def drop_table():
    from application.models.test import User
    from application import db
    add_ = User(name='Admin')
    db.session.add(add_)
    db.session.commit()

    调用命令

    查看数据库

  2.2 flask-sqlalchemy使用方法 

  2.2.1 可供参考

    flask-sqlalchemy, 还有很多其他操作命令: 可参考这

    还有这里可以参考实际操作: 去看看

  2.2.2 添加数据


# 单个
admin_role1 = User(name='Admin1')
db.session.add(admin_role1)

db.session.commit()

#
多个同时添加 admin_role1 = User(name='Admin1') admin_role2 = User(name='Admin2') admin_role3 = User(name='Admin3') db.session.add_all([admin_role1 , admin_role2 , admin_role3]) #提交更改 db.session.commit()

  2.2.3 查询数据

all() : 查询所有 类似sql语句 select * from 表名;
User.query.all()

first(): 查出第一个
User.query.first()

get() : 根据主键查
User.query.get(主键id)

count(): 数据条数
User.query.count()

还有其他的,自行了解
也可以使用这种语法
db.session.query(User).all()

    查询过滤

    一般是两个 filter filter_by

    filter_by 是简单列查询,不支持比较和逻辑查询

    filter  是复杂查询,可以支持大小,逻辑等判断查询

# 只能在里面放入等号赋值的方式查询
User.query.filter_by(name='admin', age=10).first()

# 逻辑查询
from sqlalchemy import or_,and_, not_
User.query.filter(or_(User.id>2, User.age<10)).all()

    其中还有很多查询函数

user = User.query.filter(User.name.startswith('n')).all()
user = User.query.filter(User.name.endswith("n")).all()
user = User.query.filter(User.name.contains("n")).all()

    然后 常用的排序

# 正序
User.query.order_by(User.id).all()  

# 倒序
User.query.order_by(User.id.desc()).all() 

    以上都可以组合起来用

User.query.filter(User.name.startswith('ad')).order_by(User.id.desc()).offset(2).limit(3).all()

   2.2.4 修改数据

    如果需要修改,需要先查询

  # 1.执行查询语句, 获取目标模型对象
    user = User.query.filter(User.name == 'admin').first()
    # 2.对模型对象的属性进行赋值 (更新数据)
    user.age = 9
    # 3.提交会话
    db.session.commit()

    最好的处理方式是组合一起操作,因为SQLAlchemy  默认是事务性的,分行会使操作两步,降低效率

User.query.filter(User.name == 'admin').update({'age': 9})
db.session.commit()

   2.2.5 删除数据

    这种删除会真删除,实际尽量伪删除

 # 方式1: 先查后删除
    user= User.query.filter(User.name == 'admin').first()
    # 删除数据
    db.session.delete(user)
    # 提交会话 增删改都要提交会话
    db.session.commit()

# 方式2: delete子查询
    User.query.filter(User.name == 'admin').delete()
    # 提交会话
    db.session.commit()

    

  2.3  flask-migrate

  2.3.1模型数据库同步

    配置 flask-migrate

# 创建flask 实例
app = create_app('production') from application import db migrate = Migrate(app, db)

    然后就可以在命令行进行操作

第一次操作,创建数据库操作文件
    flask db init
后续,创建数据库脚本,这个会修改对模型修改同步到数据库表
    flask db migrate
提交修改
    flask db upgrade

如果需要其他操作
    # 查看历史版本
    flask db history
    # 切换到任何版本
    flask db downgrade 版本号

 

三、问题