Flask:05-一首歌的时间掌握flask数据模型(01)

数据模型
数据库回顾
分类:
关系型数据库: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():
    # 创建对象
    # jie = User(name='八戒', email='[email protected]', age=30)
    # hou = User(name='猴哥', email='[email protected]', age=20)
    # 保存到数据库,只能保存一条数据
    # db.session.add(hou)

    bei = User(name='贝贝', email='[email protected]', age=28)
    jing = User(name='晶晶', email='[email protected]', age=18)
    huan = User(name='欢欢', email='[email protected]', age=22)
    ying = User(name='迎迎', email='[email protected]', age=23)
    ni = User(name='妮妮',email='[email protected]',
    age=20)

    # 保存到数据库,一次性保存多条数据
    db.session.add_all([bei, jing, huan, ying, ni])

    # 提交操作,若没有设置自动提交,每次执行操作都需要手动提交一次
    # 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

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.www.fengshen157.com filter(User.email.contains('ng')).all()
# 以指定内容开头
# users = User.query.www.baidu620.com/ filter(User.email.startswith('fe')).all()
# 以指定内容结尾
# users = User.query.www.thd178.com filter(User.email.endswith('.com')).all()
# 模糊匹配
# users = User.query.filter(www.thd540.com User.email.like('l%')).all()
users = User.query.filter(User.email.notlike('l%')).all()
逻辑

from sqlalchemy import and_, or_

# 默认的关系就是逻辑与
# users = User.query.filter(www.longboshyl.cn User.id > 3, User.age > 20).all()
# 与上式等价
# users = User.query.www.dfgjpt.com/ filter(and_(User.id > 3, User.age > 20)).all()
# 逻辑或
users = User.query.filter(or_(User.id www.zhongdayule.cn/> 3, User.age > 20)).all()

猜你喜欢

转载自blog.csdn.net/li123128/article/details/82942218