zoukankan      html  css  js  c++  java
  • Flask数据库基本操作

    Flask数据库基本操作

    在Flask-SQLAlchemy中,插入、修改、删除操作,均由数据库会话管理。

    会话用 db.session 表示。在准备把数据写入数据库前,要先将数据添加到会话中然后调用 commit() 方法提交会话。

    在 Flask-SQLAlchemy 中,查询操作是通过 query 对象操作数据。

    最基本的查询是返回表中所有数据,可以通过过滤器进行更精确的数据库查询。

    在视图函数中定义模型类

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
     
     
    app = Flask(__name__)
     
    #设置连接数据库的URL
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/test'
     
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
    #查询时会显示原始SQL语句
    app.config['SQLALCHEMY_ECHO'] = True
    db = SQLAlchemy(app)
     
    class Role(db.Model):
        # 定义表名
        __tablename__ = 'roles'
        # 定义列对象
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(64), unique=True)
        us = db.relationship('User', backref='role')
     
        #repr()方法显示一个可读字符串
        def __repr__(self):
            return 'Role:%s'% self.name
     
    class User(db.Model):
        __tablename__ = 'users'
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(64), unique=True, index=True)
        email = db.Column(db.String(64),unique=True)
        password = db.Column(db.String(64))
        role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
     
        def __repr__(self):
            return 'User:%s'%self.name
    if __name__ == '__main__':
        app.run(debug=True)
    View Code

    模型之前的关联

    一对多

     
    class Role(db.Model):
        ...
        #关键代码
        us = db.relationship('User', backref='role', lazy='dynamic')
        ...
     
    class User(db.Model):
        ...
        role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    View Code

    其中realtionship描述了Role和User的关系。在此文中,第一个参数为对应参照的类"User"第二个参数backref为类User申明新属性的方法第三个参数lazy决定了什么时候SQLALchemy从数据库中加载数据如果设置为子查询方式(subquery),则会在加载完Role对象后,就立即加载与其关联的对象,这样会让总查询数量减少,但如果返回的条目数量很多,就会比较慢设置为 subquery 的话,role.users 返回所有数据列表另外,也可以设置为动态方式(dynamic),这样关联对象会在被使用的时候再进行加载,并且在返回前进行过滤,如果返回的对象数很多,或者未来会变得很多,那最好采用这种方式设置为 dynamic 的话,role.users 返回查询对象,并没有做真正的查询,可以利用查询对象做其他逻辑,比如:先排序再返回结果

    多对多

    registrations = db.Table('registrations',  
        db.Column('student_id', db.Integer, db.ForeignKey('students.id')),  
        db.Column('course_id', db.Integer, db.ForeignKey('courses.id'))  
    )  
    class Course(db.Model):
        ...
    class Student(db.Model):
        ...
        courses = db.relationship('Course',secondary=registrations,  
                                        backref='students',  
                                        lazy='dynamic')
    View Code

    常用的SQLAlchemy查询过滤器

    过滤器说明
    filter() 把过滤器添加到原查询上,返回一个新查询
    filter_by() 把等值过滤器添加到原查询上,返回一个新查询
    limit 使用指定的值限定原查询返回的结果
    offset() 偏移原查询返回的结果,返回一个新查询
    order_by() 根据指定条件对原查询结果进行排序,返回一个新查询
    group_by() 根据指定条件对原查询结果进行分组,返回一个新查询

    常用的SQLAlchemy查询执行器

    方法说明
    all() 以列表形式返回查询的所有结果
    first() 返回查询的第一个结果,如果未查到,返回None
    first_or_404() 返回查询的第一个结果,如果未查到,返回404
    get() 返回指定主键对应的行,如不存在,返回None
    get_or_404() 返回指定主键对应的行,如不存在,返回404
    count() 返回查询结果的数量
    paginate() 返回一个Paginate对象,它包含指定范围内的结果

    创建表:

    db.create_all()

    删除表:

    db.drop_all()

    插入一条数据:

    ro1 = Role(name='admin')
    db.session.add(ro1)
    db.session.commit()
    #再次插入一条数据
    ro2 = Role(name='user')
    db.session.add(ro2)
    db.session.commit()

    一次插入多条数据:

    us1 = User(name='wang',email='wang@163.com',password='123456',role_id=ro1.id)
    us2 = User(name='zhang',email='zhang@189.com',password='201512',role_id=ro2.id)
    us3 = User(name='chen',email='chen@126.com',password='987654',role_id=ro2.id)
    us4 = User(name='zhou',email='zhou@163.com',password='456789',role_id=ro1.id)
    us5 = User(name='tang',email='tang@itheima.com',password='158104',role_id=ro2.id)
    us6 = User(name='wu',email='wu@gmail.com',password='5623514',role_id=ro2.id)
    us7 = User(name='qian',email='qian@gmail.com',password='1543567',role_id=ro1.id)
    us8 = User(name='liu',email='liu@itheima.com',password='867322',role_id=ro1.id)
    us9 = User(name='li',email='li@163.com',password='4526342',role_id=ro2.id)
    us10 = User(name='sun',email='sun@163.com',password='235523',role_id=ro2.id)
    db.session.add_all([us1,us2,us3,us4,us5,us6,us7,us8,us9,us10])
    db.session.commit()
     
     
    """
    查询所有用户数据
    查询有多少个用户
    查询第1个用户
    查询id为4的用户[3种方式]
    查询名字结尾字符为g的所有数据[开始/包含]
    查询名字不等于wang的所有数据[2种方式]
    查询名字和邮箱都以 li 开头的所有数据[2种方式]
    查询password是 `123456` 或者 `email` 以 `itheima.com` 结尾的所有数据
    查询id为 [1, 3, 5, 7, 9] 的用户列表
    查询name为liu的角色数据
    查询所有用户数据,并以邮箱排序
    每页3个,查询第2页的数据
    """
    View Code

    查询:filter_by精确查询:

    返回名字等于wang的所有人

    User.query.filter_by(name='wang').all()

    first()返回查询到的第一个对象:

    User.query.first()

    all()返回查询到的所有对象:

    User.query.all()

    filter模糊查询,返回名字结尾字符为g的所有数据:

    User.query.filter(User.name.endswith('g')).all()

    get():参数为主键,如果主键不存在没有返回内容:

    User.query.get()

    逻辑非,返回名字不等于wang的所有数据:

    User.query.filter(User.name!='wang').all()

    not_ 相当于取反:

    from sqlalchemy import not_
    User.query.filter(not_(User.name=='chen')).all()

    逻辑与,需要导入and,返回and()条件满足的所有数据:

    from sqlalchemy import and_
    User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()

    逻辑或,需要导入or_:

    from sqlalchemy import or_
    User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()

    查询数据后删除:

    user = User.query.first()
    db.session.delete(user)
    db.session.commit()
    User.query.all()

    更新数据:

    user = User.query.first()
    user.name = 'dong'
    db.session.commit()
    User.query.first()

    关联查询示例:

        角色和用户的关系是一对多的关系,一个角色可以有多个用户,一个用户只能属于一个角色。

    查询角色的所有用户:

    #查询roles表id为1的角色
    ro1 = Role.query.get(1)
    #查询该角色的所有用户
    ro1.us.all()

    查询用户所属角色:

    #查询users表id为3的用户
    us1 = User.query.get(3)
    #查询用户属于什么角色
    us1.role
  • 相关阅读:
    python模块--time模块
    python模块--如何相互调用自己写的模块
    Animating Views Using Scenes and Transitions
    fragment 切换
    android textview 设置text 字体
    android intent 5.1
    android EditView ime
    animation of android (4)
    animation of android (3)
    animation of android (2)
  • 原文地址:https://www.cnblogs.com/ls011218/p/11817256.html
Copyright © 2011-2022 走看看