flask-数据模型01

版权声明:转载请注明,否则将追究相关法律责任 https://blog.csdn.net/zangshuge/article/details/82024197

数据模型

数据库回顾

  • 分类:
    • 关系型数据库:MySQL、sqlite、…
    • 非关系型数据库:Redis、MongoDB、…
  • 操作:
    • 执行原生SQL语句,每次都需要拼接SQL语句,非常繁琐而且特别容易出错。
    • ORM(对象关系映射),使用ORM可以通过对对象的操作完成对数据库的操作。

flask-sqlalchemy

  • 说明:其实是sqlalchemy扩展库在flask中的移植库,通过了绝大多数关系型数据库的支持(ORM)

  • 安装:pip install flask-sqlalchemy

  • 连接地址配置:

    • 名称:SQLALCHEMY_DATABASE_URI
    • 格式:
    • sqlite:sqlite:/// + 数据库文件名
    • MySQL:数据库名+驱动名://用户名:密码@主机:端口/数据库
  • 使用:

    
    # 配置数据连接地址
    
    base_dir = os.path.dirname(__file__)
    database_uri = 'sqlite:///' + os.path.join(base_dir, 'data.sqlite')
    app.config['SQLALCHEMY_DATABASE_URI'] = database_uri
    
    # 禁止数据的修改追踪(需要消耗资源)
    
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    
    
    # 创建数据库操作对象
    
    db = SQLAlchemy(app)
    
    
    # 设计模型类
    
    class User(db.Model):
      # 表名默认会将模型名转为小写加下划线的形式
      # 如:UserModel => user_model
      # 指定表名
      __tablename__ = 'users'
      id = db.Column(db.Integer, primary_key=True)
      name = db.Column(db.String(20), unique=True)
      email = db.Column(db.String(32), unique=True)   
  • 数据表操作

    @app.route('/create/')
    def create():
      # 创建数据表
      db.create_all()
      return '数据表已创建'
    
    @app.route('/drop/')
    def drop():
      db.drop_all()
      return '数据表已删除'
    
    
    # 添加终端命令,完成数据表的创建
    
    @manager.command
    def createall():
      # 先删除原来的,副作用很大
      db.drop_all()
      # 然后再创建
      db.create_all()
      return '数据表已创建'
    
    
    # 添加终端命令,完成数据表的删除
    
    @manager.command
    def dropall():
      if prompt_bool('您确定要删库跑路吗?'):
          db.drop_all()
          return '数据表已删除'
      return '删库有风险,操作需谨慎!'

    执行终端命令:python manage.py createall,即可创建数据表

数据库迁移

  • 说明:将数据模型的更改应用到数据表的操作叫数据库迁移。flask-migrate就是专门做迁移的扩展库。

  • 安装:pip install flask-migrate

  • 使用:

    from flask_migrate import Migrate
    
    
    # 创建数据库迁移对象
    
    migrate = Migrate(app, db)
    
    
    # 将迁移命令添加到终端
    
    manager.add_command('db', MigrateCommand)
  • 迁移:

    • 初始化,只需要一次,创建用户存放迁移脚本的目录及相关文件。
    python manage.py db init
    • 根据数据模型与数据表,生成迁移脚本。
    python manage.py db migrate
    • 执行迁移脚本
    python manage.py db upgrade
  • 提示:

    • 初始化操作只需要一次,以后生成迁移脚本与执行迁移脚本循环执行即可完成数据库的迁移。
    • 不是每次迁移都会成功,迁移出错时需要手动解决。

CURD操作

  • 增加数据

    
    # 设置自动提交操作,请求结束时无论如何都会提交
    
    app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
    
    
    # 增加数据
    
    @app.route('/insert/')
    def insert():
      # 创建对象
      # liang = User(name='亮亮', email='[email protected]', age=30)
      # zhao = User(name='昭昭', email='[email protected]', age=20)
      # 保存到数据库,只能保存一条数据
      # db.session.add(zhao)
    
      peng = User(name='鹏鹏', email='[email protected]', age=28)
      fei = User(name='飞飞', email='[email protected]', age=18)
      long = User(name='龙龙', email='[email protected]', age=22)
      guo = User(name='果果', email='[email protected]', age=23)
    
      # 保存到数据库,一次性保存多条数据
      db.session.add_all([peng, fei, long, guo])
    
      # 提交操作,若没有设置自动提交,每次执行操作都需要手动提交一次
      # db.session.commit()
    
      return '数据已添加'
  • 查询数据

    
    # 查询操作
    
    @app.route('/select/<uid>/')
    def select(uid):
    
    # 根据主键进行查询,找到返回对象,没找到返回None
    
    user = User.query.get(uid)
    if user:
        return user.name
    return '查无此人'
  • 修改数据

    
    # 修改数据
    
    @app.route('/update/<uid>/')
    def update(uid):
      user = User.query.get(uid)
      if user:
          user.email = '[email protected]'
          # 再次添加到数据库即可
          db.session.add(user)
          return '数据已修改'
      return '查无此人'
  • 删除数据

    
    # 删除数据
    
    @app.route('/delete/<uid>/')
    def delete(uid):
      user = User.query.get(uid)
      if user:
          db.session.delete(user)
          return '数据已删除'
      return '查无此人'

模型设计参考

  • 常见的字段类型
字段类型 python类型 说明
Integer int 整型(32)
SmallInteger int 整型(16)
BigInteger int/long 整型(64)
Float float 浮点型
String str 变长字符串
Text str 不受限制的文本
Boolean bool 布尔值,True/False
Date datetime.date 日期
Time datetime.time 时间
DateTime datetime.datetime 日期时间
Interval datetime.timedelta 时间间隔
PickleType pickle.dumps() 使用pickle模块序列化后的python对象
LargeBinary bytes 任意大的二进制数据

- 常见字段选项

选项 说明
primary_key 是否作为主键索引,默认为False
autoincrement 是否设置字段自增,默认为False
unique 是否作为唯一索引,默认为False
index 是否作为普通索引,默认为False
nullable 字段是否可以为空,默认为True
default 设置默认值

- 总结:

  • 插入数据可以不传值的情况:自增的字段、可以为空的字段、有默认值的字段
  • 使用flask-sqlalchemy时每个模型都需要有一个主键,通常主键字段名称为id
  • 数据模型类名与数据表中的名字
    • 默认:会将模型名转换为小写加下划线的方式,如:UserModel => user_model
    • 指定:通过类属性__tablename__指定表名

各种查询

  • 说明:在数据库的操作中,绝大多数都是查询操作,而且这些操作都是通过方法来实现的。

  • 常见操作:

操作 说明
get 根据主键查询,查到返回对象,没查到返回None
get_or_404 根据主键查询,查到返回对象,没查到报404错
first 返回第一条数据,没有时返回None
first_or_404 返回第一条数据,没有时报404错
all 查询所有数据组成的列表
limit 限制结果集数量,返回时查询对象
offset 结果集偏移数量,返回时查询对象
order_by 排序,指定字段后,默认按升序排序(asc),降序(desc),可以指定多个字段
count 统计个数

- 聚合函数:max、min、sum、avg、count

“`python
from sqlalchemy import func

@app.route(‘/query/’)
def query():
# 聚合函数
# max_age = db.session.query(func.max(User.age)).scalar()
max_age = db.session.query(func.min(User.age)).scalar()
return str(max_age)
“`

  • 指定条件查询

    @app.route('/query/')
    def query():
    
    # 指定等值条件
    
      # users = User.query.filter_by(age=18).all()
      # 指定任意条件
      users = User.query.filter(User.age > 18).all()
      return ','.join(u.name for u in users)

filter条件查询

  • 关系

    >, __gt__:大于
    示例:    # users = User.query.filter(User.age > 20).all()
        # 等价于上式
        users = User.query.filter(User.age.__gt__(20)).all()
    >=,__ge__:大于等于
    <, __lt__:小于
    <=,__le__:小于等于
    ==,__eq__:等于
    !=,__ne__:不等于
  • 范围

    users = User.query.filter(User.id.between(1, 3)).all()
    users = User.query.filter(User.id.in_((1, 3, 5))).all()
    users = User.query.filter(User.id.notin_((1, 3, 5))).all()
  • 内容

    
    # 包含指定内容
    
    
    # users = User.query.filter(User.email.contains('ng')).all()
    
    
    # 以指定内容开头
    
    
    # users = User.query.filter(User.email.startswith('fe')).all()
    
    
    # 以指定内容结尾
    
    
    # users = User.query.filter(User.email.endswith('.com')).all()
    
    
    # 模糊匹配
    
    
    # users = User.query.filter(User.email.like('l%')).all()
    
    users = User.query.filter(User.email.notlike('l%')).all()
  • 逻辑

    from sqlalchemy import and_, or_
    
    
    # 默认的关系就是逻辑与
    
    
    # users = User.query.filter(User.id > 3, User.age > 20).all()
    
    
    # 与上式等价
    
    
    # users = User.query.filter(and_(User.id > 3, User.age > 20)).all()
    
    
    # 逻辑或
    
    users = User.query.filter(or_(User.id > 3, User.age > 20)).all()

猜你喜欢

转载自blog.csdn.net/zangshuge/article/details/82024197
今日推荐