数据查询

Flask-SQLAlchemy 查询中的查询是通过query对象操作数据。通过过滤器进行条件限定精确查询。

基本查询:

查询所有数据

模型类.query.all()

__repr__ 方法:

查询默认返回的是id,如果要直观的看到查询出来的是什么数据,可以在模型类中添加一个__repr__ 方法,类似于django模型类中的__str__方法。

    def __repr__(self):
        return "Father: %s" % self.name

添加__repr__ 方法后再查询,直接返回对象显示的是repr方法的返回值。

>>> from code import Father
>>> Father.query.all()
[Father: 小头爸爸]

常用查询方法

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

查询过滤器

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

构造查询数据

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)  # type:Flask

# 设置连接的数据库
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@192.168.20.233:3306/py'
# 追踪对象的修改并且发送信号
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

# 创建数据库对象
db = SQLAlchemy(app)

class Movie(db.Model):
    """创建一个电影模型类"""
    # 表名
    __tablename__ = 'movie'
    # id主键列,整数类型,自增
    id = db.Column(db.Integer, primary_key=True)
    # name,可变长字符串类型
    name = db.Column(db.String(20))
    # 关系字段,不是数据库中真实存在的字段,而是为了方便查询添加的属性
    cast = db.relationship('Cast', backref='Movie')
    def __repr__(self):
        return "Movie: %s " % self.name


class Cast(db.Model):
    """演员模型类"""
    # id主键列,整数类型,自增
    id = db.Column(db.Integer, primary_key=True)
    # name,可变长字符串类型
    name = db.Column(db.String(20))
    # 外键关联id
    movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'))
    def __repr__(self):
        return "Cast: %s " % self.name


if __name__ == '__main__':
    # 删除所有表,注意这条是危险命令,会将数据库中的表物理删除。在实际生产环境下勿用。
    db.drop_all()
    # 创建所有表
    db.create_all()
    m1 = Movie(name='大话西游')
    m2 = Movie(name='功夫')
    db.session.add_all([m1, m2])
    db.session.commit()
    cast_list = []
    for i in ['周星驰', '朱茵', '吴孟达', '莫文蔚']:
        c = Cast(name=i, movie_id=m1.id)
        cast_list.append(c)
    for i in ['周星驰', '梁小龙', '元华']:
        c = Cast(name=i, movie_id=m2.id)
        cast_list.append(c)
    db.session.add_all(cast_list)
    db.session.commit()

查询演示在shell中演示

进入python shell ,导入模块

filter_by 精确匹配查询,条件只能是本表的字段

>>> Cast.query.filter_by(name='周星驰').all()
[Cast: 周星驰 , Cast: 周星驰 ]

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

>>> Cast.query.first()
Cast: 周星驰

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

>>> Cast.query.all()
[Cast: 周星驰 , Cast: 朱茵 , Cast: 吴孟达 , Cast: 莫文蔚 , Cast: 周星驰 , Cast: 梁小龙 , Cast: 元华 ]

filter 模糊查询

>>> Cast.query.filter(Cast.name.startswith('周')).all()
[Cast: 周星驰 , Cast: 周星驰 ]
>>> Cast.query.filter(Cast.name.endswith('龙')).all()
[Cast: 梁小龙 ]
>>> Cast.query.filter(Cast.name=='周星驰').all()
[Cast: 周星驰 , Cast: 周星驰 ]

like 正则 模糊匹配,跟mysql中的like一样。

>>> Cast.query.filter(Cast.name.like('周%%')).all()
[Cast: 周星驰 , Cast: 周星驰 ]

逻辑运算

and_ 逻辑与

or_ 逻辑非

not_ 取反

查询中使用逻辑运算需要先导入

from sqlalchemy import and_,or_,not_
#查询名字为'周星驰'并且movie_id为2的演员数据。
In [11]:Cast.query.filter(and_(Cast.name=='周星驰',Cast.movie_id==2)).all()
Out[11]:[Cast: 周星驰 ]

#查询名字为'周星驰'或者id为2的演员数据。
In [12]:Cast.query.filter(or_(Cast.name=='周星驰',Cast.movie_id==2)).all()
Out[12]:[Cast: 周星驰 , Cast: 周星驰 , Cast: 梁小龙 , Cast: 元华 ]

#查询名字不为'周星驰'的演员
In [13]: Cast.query.filter(not_(Cast.name=='周星驰')).all()
Out[13]: [Cast: 朱茵 , Cast: 吴孟达 , Cast: 莫文蔚 , Cast: 梁小龙 , Cast: 元华 ]

关联查询:

关联查询使用到 relationship 字段。这个字段不是真实存在于数据库中的,而是为了方便查询定义的。

查询出一个演员可以快速将他对应的电影查询出来,或者反过来,知道一部电影,可以直接将电影的演员全部查询出来。

查询名字为'朱茵'的演员,并且查出她出演的电影:

# 查询出演员'朱茵'
In [10]: actor  = Cast.query.filter(Cast.name=='朱茵').all()
In [11]: actor
Out[11]: [Cast: 朱茵 ]

# 直接通过 relationship 中定义的 backref 属性可以直接查询出演员对应的电影。 
In [12]: actor[0].Movie
Out[12]: Movie: 大话西游



In [13]: movie = actor[0].Movie

In [14]: movie
Out[14]: Movie: 大话西游
# 通过电影直接查询出所有演员
In [15]: movie.cast
Out[15]: [Cast: 周星驰 , Cast: 朱茵 , Cast: 吴孟达 , Cast: 莫文蔚 ]

删除数据:

先查询后删除

#  删除演员表中的'吴孟达'

In [2]: Cast.query.filter(Cast.name=='吴孟达').first()
Out[2]: Cast: 吴孟达
# 将数据查询出来
In [3]: actor = Cast.query.filter(Cast.name=='吴孟达').first()
# 删除对象
In [4]: db.session.delete(actor)
# 提交到数据库
In [5]: db.session.commit()
# 查询所有演员,'吴孟达' 已经被删除
In [6]: Cast.query.all()
Out[6]: [Cast: 周星驰 , Cast: 朱茵 , Cast: 莫文蔚 , Cast: 周星驰 , Cast: 梁小龙 , Cast: 元华 ]

更新数据:


# 将'梁小龙'的名字改成'火云邪神'

# 第一个种方式
In [6]: Cast.query.all()
Out[6]: [Cast: 周星驰 , Cast: 朱茵 , Cast: 莫文蔚 , Cast: 周星驰 , Cast: 梁小龙 , Cast: 元华 ]

# 先将'梁小龙'查询出来
In [8]: actor = Cast.query.filter(Cast.name=='梁小龙').first()

# 将'梁小龙'的名字改成'火云邪神'
In [9]: actor.name = '火云邪神'

In [10]: db.session.add(actor)

In [11]: db.session.commit()

In [12]: Cast.query.all()
Out[12]: [Cast: 周星驰 , Cast: 朱茵 , Cast: 莫文蔚 , Cast: 周星驰 , Cast: 火云邪神 , Cast: 元华 ]


# 第二种方式  update 方式

# 将'朱茵'  修改成'紫霞仙子'

In [19]:Cast.query.filter(Cast.name=='朱茵').update({'name':'紫霞仙子'})

In [20]: Cast.query.all()
Out[20]: [Cast: 周星驰 , Cast: 紫霞仙子 , Cast: 莫文蔚 , Cast: 周星驰 , Cast: 火云邪神 , Cast: 元华 ]
Iyoyo电子书 一本集作者多年开发经验的python电子书 all right reserved,powered by Gitbook文件修订时间: 2022年 11:36:31