在使用Flask开发的时候,用到Flask-Sqlalchemy进行数据库操作,查
作为数据库操作重要的部分,查询语句的设计直接关系到网站性能,真实体验到查
操作的重要性。
本片文章主要记录Flask-Sqlalchemy查询操作,也是开发工作中使用过的在此做个记录,先定义多对多的关系,方便举栗子,这是开发中的使用的例子,也可以理解成一般的多对多关系。
1 | from exts import db |
2 | import datetime |
3 | |
4 | class Tags(db.Model): #标签表 |
5 | ''' |
6 | 漏洞的标签:id、名称、创建时间 |
7 | ''' |
8 | __tablename__ = 't_tags' |
9 | id = db.Column(db.Integer, primary_key=True, autoincrement=True) |
10 | name = db.Column(db.String(50), nullable=True, comment='漏洞标签名称') |
11 | create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='加入时间') |
12 | vuls = db.relationship('Vuls', secondary=vul_tag, backref='tags') # 设置关系,通过中间表`t_vul_tag`实现 |
13 | |
14 | class Vuls(db.Model): |
15 | ''' |
16 | 靶场漏洞库 |
17 | ''' |
18 | __tablename__ = 't_vuls' |
19 | id = db.Column(db.Integer, primary_key=True, autoincrement=True) #uuid |
20 | name = db.Column(db.String(255), nullable=True, comment='漏洞名称') |
21 | create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='加入时间') |
22 | |
23 | vul_tag = db.Table( #中间表,表名`t_vul_tag` |
24 | 't_vul_tag', |
25 | db.Column('t_vul_id', db.Integer, db.ForeignKey('t_vuls.id'), primary_key=True), |
26 | db.Column('t_tag_id', db.Integer, db.ForeignKey('t_tags.id'), primary_key=True) |
27 | ) |
0x01 简单操作
普通查询
- 根据主键(id)获取某一标签
1
tag = Tags.query.get(id)
- 获取所有的标签
1
tags = Tags.query.all()
- 根据非主键获取某一标签(name)
1
tag = Tags.query.filter(Tags.name=='xxx').first()
2
tag = Tags.query.filter_by(name='xxx').first() #另种写法
- 根据创建时间倒序,获取所有标签(desc)
1
tags = Tags.query.order_by(Tags.create_time.desc())
- 获取所有标签的数量(count)
1
count = Tags.query.count()
- 获取10个标签
1
tags = Tags.query.limit(10)
- 切片查询,获取标签的1-10(多用于分页)(slice)
1
tags = Tags.query.slice(1,11)
- 查询标签name中带有xxx的某一标签模糊查询(like)
1
tag = Tags.query.filter(Tags.name.like("%xxx%")).first()
- 查询标签name中包含xxx的某个标签(contains)
1
tag = Tags.query.filter(Tags.name.contains('xxx')).first()
- 查询标签name的小写等于xxx的标签(func.lower)
1
from sqlalchemy import func
2
tag = Tags.query.filter(func.lower(Tags.name)=='xxx').first()
- 查询标签表name一列(with_entitles)
1
names = Tags.query.with_entitles(Tags.name).all()
- 查询标签表name一列去重(distinct)
1
names = Tags.query.with_entitles(Tags.name).distinct().all()
- 查询标签name以x开头的所有标签(startswith)
1
tags = Tags.query.filter(Tags.name.startswith('x')).all()
通过关系查询
- 查询标签name=xxx下所有的漏洞库
1
vuls = Tags.query.filter_by(name='xxx').vuls
- 查询漏洞库name=xxx的所有标签
1
tags = Vuls.query.filter_by(name='xxx').tags
- 将标签name=xxx,添加到name=yyy的漏洞库上
1
tag = Tage.query.filter_by(name='xxx').first()
2
tags = Vuls.query.filter_by(name='xxx').tags
3
tags.append(tag)
其实多对多的操作,就是
list
操作,多的方面是一个列表,对应的增删改,及为列表的增删改
0x02 进阶操作
时间查询
- 查询指定创建日期的所有标签(extract)
1
from sqlalchemy import extract
2
from datetime import date
3
today = date.today()
4
tags = Tags.query.filter(extract('year', Tags.create_time)==today.year,
5
extract('month', Tags.create_time)==today.month,
6
extract('day', Tags.create_time)==today.day).all()
- 查询某个时间段之间的所有创建的标签(between)
1
from sqlalchemy import between
2
tags = Tags.query.filter(Tags.create_time.between('1990-01-01','1990-01-02'))
多条件查询
- 查询name=xxx并且create_time=xxx的某个标签(and_)
1
from sqlalchemy import and_
2
tags = Tags.query.filter(and_(Tags.name=='xxx', Tags.create_time=='xxx')).first()
- 查询name=xxx或者create_time=xxx的某个标签(or_)
1
from sqlalchemy import or_
2
tags = Tags.query.filter(or_(Tags.name=='xxx', Tags.create_time=='xxx')).first()
- 查询标签name在[‘xxx’,’yyy’,’zzz’]列表中的所有(in_)
1
tags = Tags.query.filter(Tags.name.in_(['xxx','yyy','zzz'])).all()
- 查询标签name不是以x开头的所有标签(not_)
1
from sqlalchemy import not_
2
tags = Tags.query.filter(not_(Tags.name.startswith('x'))).all()
工作中遇到的