资讯专栏INFORMATION COLUMN

Tornado-09、SQLalchemy的查询

dendoink / 1412人阅读

摘要:前两个查询的是所以返回结果也是一个对象,但是查询的是属性值,所以返回的是属性值。多表查询多表查询也是必须要掌握的知识点。原生的查询以及其他使用再次强调,使用或者原生没有绝对的那个好一点,怎么方便怎么使用。

1.带条件的查询

查询是最常用的,对于各种查询我们必须要十分清楚,首先是带条件的查询

#查询特定字段
rows = session.query(User).filter_by(username="budong").all()
print(rows)  # 返回User对象
rows1 = session.query(User).filter(User.username=="budong").all()
print(rows1)  # 返回User对象
rows2 = session.query(User.username).filter(User.

username=="budong").all() # 返回的是值

print(rows2)
rows3 = session.query(User.username).filter(User.username=="budong")
print(rows3)  # 返回的是值

filter_by和filter都是过滤条件,只是用法有区别filter_by里面不能用!=还有> < 等等,所有filter用得更多,filter_by只能用=。

前两个查询的是User,所以返回结果也是一个对象,但是rows2查询的是属性值,所以返回的是属性值。

rows3可以看到SQLAlchemy转成的SQL语句,SQLAlchemy最后都是会转成SQL语句,通过这个方法可以查看原生SQL,甚至有些时候我们需要把SQLAlchemy转成的SQL交给DBA审查,合适的才能使用。

查询要知道查询结果的返回怎样的数据

#基本查询
print( session.query(User).filter(User.username=="budong").all() )
print( session.query(User).filter(User.username=="budong").first())
print( session.query(User).filter(User.username=="budong").one())
print( session.query(User).get(2))

上面三条记录,第一个查出所有符合条件的记录,第二个查出所有符合记录的第一条记录,第三个返回一个对象,如果结果有多条就会报错,第四个通过主键获取记录

除此之外,我们偶尔也会需要限制返回的结果数量

#限制查询返回结果
print( session.query(User).filter(User.username!="budong").limit(2).all())
# 最多返回两条记录 
print( session.query(User).filter(User.username!="budong").offset(2).all())
# 从第3条记录开始返回
print( session.query(User).filter(User.username!="budong").slice(2,3).all())
#  截取第2到第3条
#可以排序之后再进行限制
from sqlalchemy import desc
print( session.query(User).filter(User.username!="budong").order_by(User.username).all())
print( session.query(User).filter(User.username!="budong").order_by(desc(User.username)).slice(1,3).all())

第一个是限制返回条数,从第一条开始;第二个是从第三条开始返回查询结果;第三个是切片返回记录。

order_by默认是顺序,desc是降序。

还有其他的带条件查询

#不等于
print( session.query(User).filter(User.username!="budong").all() )
#模糊匹配 like
print( session.query(User).filter(User.username.like("budong")).all() )
print( session.query(User).filter(User.username.notlike("budong")).all() )
#成员属于  in_
print( session.query(User).filter(User.username.in_(["budong","tuple"])).all() )
#成员不属于  notin_
print( session.query(User).filter(User.username.notin_(["budong","tuple"])).all() )
#空判断
print( session.query(User).filter(User.username==None).all() )
print( session.query(User).filter(User.username.is_(None)).all() )
print( session.query(User).filter(User.username.isnot(None)).all() )
#多条件
print( session.query(User).filter(User.username.isnot(None),User.password=="qwe123").all() )
#选择条件
from sqlalchemy import or_,and_,all_,any_
print( session.query(User).filter(or_(User.username=="budong",User.password=="qwe123")).all() )
print( session.query(User).filter(and_(User.username=="budong",User.password=="111")).all() )

以上是各种带条件的查询,大家知道怎么使用,但是需要注意的是,所以的模糊匹配是十分耗费时间的,能不用就尽量不要用。

当然还有聚合函数的使用

#聚合函数的使用
from sqlalchemy import func,extract
print( session.query(User.password,func.count(User.id)).group_by(User.password).all() )  # 按密码进行分组 统计密码相同的有多少个
print( session.query(User.password,func.count(User.id)).group_by(User.password).having(func.count(User.id)>1).all() )  # 查出所有id>1的信息
print( session.query(User.password,func.sum(User.id)).group_by(User.password).all() )
print( session.query(User.password,func.max(User.id)).group_by(User.password).all() )
print( session.query(User.password,func.min(User.id)).group_by(User.password).all() )
#使用extract提取时间中的分钟或者天来分组
print( session.query(extract("minute", User.creatime).label("minute"),func.count("*").label("count")).group_by("minute").all() )
print( session.query(extract("day", User.creatime).label("day"),func.count("*").label("count")).group_by("day").all() )

这里只是告诉大家的用法,其中group_by是分组,如果要使用聚合函数,就必须导入func,label是取别名的意思 。

2.表关系查询

对于有表关系的,也有些不同的查询,首先我们来建立一个有外键关系的表

from sqlalchemy.orm import relationship
from sqlalchemy import ForeignKey

class UserDetails(Base):
    __tablename__ = "user_details"
    id = Column(Integer,primary_key=True,autoincrement=True)
    id_card = Column(Integer,nullable=False,unique=True)
    lost_login = Column(DateTime)
    login_num = Column(Integer,default=0)
    user_id = Column(Integer,ForeignKey("user.id"))

    userdetail_for_foreignkey = relationship("User",backref="details",uselist=False,cascade="all")

    def __repr__(self):
        return ""%(
            self.id,
            self.id_card,
            self.login_login,
            self.login_num,
            self.user_id
        )

这里要注意relationship默认是一对多的关系,使用uselist=False则表示一对一的关系,cascade 是自动关系处理,就和MySQL中的ON DELETE类似,但是有区别,参数选项如下:

cascade 所有的可选字符串项是:

all , 所有操作都会自动处理到关联对象上.

save-update , 关联对象自动添加到会话.

delete , 关联对象自动从会话中删除.

delete-orphan , 属性中去掉关联对象, 则会话中会自动删除关联对象.

merge , session.merge() 时会处理关联对象.

refresh-expire , session.expire() 时会处理关联对象.

expunge , session.expunge() 时会处理关联对象.

有如上的表关系之后,查询可以十分方便

#表关系查询
row = session.query(UserDetails).all()
print(row,dir(row[0]))
row = session.query(User).filter(User.id==1).first()
print(row,dir(row))
print(row.details)
print(row.details[0].lost_login)

relationship会在User表里面添加一个属性,通过这个属性就可以查询对应的user_details表中的所有字段。省去了很多的代码。

3.多表查询

多表查询也是必须要掌握的知识点。以下是常见的几种表关联方式,需要熟练掌握。

#多表查询
print( session.query(UserDetails,User).all() )  #这个是 cross join
print( session.query(UserDetails,User).filter(User.id==UserDetails.id).all() )  #这是也是cross join 但是加上了where条件

print( session.query(User.username,UserDetails.lost_login).join(UserDetails,UserDetails.id==User.id).all() )  #这个是inner join

print( session.query(User.username,UserDetails.lost_login).outerjoin(UserDetails,UserDetails.id==User.id).all() )  #这个才是左连接,sqlalchemy没有右连接

q1 = session.query(User.id)
q2 = session.query(UserDetails.id)
print(q1.union(q2).all())  #这个是union关联


除了上面的几种关联方式,子表查询也是用得很多的,也是要掌握的

from sqlalchemy import all_,any_
sql_0 = session.query(UserDetails.lost_login).subquery()  #这是声明一个子表
print( session.query(User).filter((User.creatime > all_(sql_0)) ).all()  )
print( session.query(User).filter((User.creatime > any_(sql_0)) ).all()  )

注意any_和all_的区别,all_要求的是所有都满足,any_只需要有满足的就行。

4.原生SQL的查询以及其他使用

再次强调,使用ORM或者原生SQL没有绝对的那个好一点,怎么方便怎么使用。

#第一步写好原生的sql,如果需要传递参数,可以使用字符串拼接的方式
sql_1 = """
    select * from `user`
"""
#第二步执行,得到返回的结果
row = session.execute(sql_1)
print(row,dir(row))
#第三步,自己控制得到数据的方式
print( row.fetchone() )
print( row.fetchmany() )
print( row.fetchall() )
#也可以循环获得
for i in row:
    print("===",i)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44709.html

相关文章

  • Flask-SQLAlchemy 学习总结

    摘要:初始化和配置对象关系映射。的则需要在中声明。例如配置信息中指出是可以绑定多个数据库引擎。是通过解决一对多的关系。将会返回学院学生人数将会返回学生的学院信息的类实例。处理关系对象查询中有详细的说明。 初始化和配置 ORM(Object Relational Mapper) 对象关系映射。指将面对对象得方法映射到数据库中的关系对象中。Flask-SQLAlchemy是一个Flask扩展,能...

    whataa 评论0 收藏0
  • Python-SQLAlchemy:第1节:SQLAlchemy入门

    摘要:下一篇文章第节查询条件设置是编程语言下的一款开源软件。提供了工具包及对象关系映射工具,使用许可证发行。在关闭连接时会自动进行事务提交操作。引入多条件查询时使用。由于上下文函数退出时会自动提交事务,所以无需显示的调用使新增生效。 下一篇文章:Python-SQLAlchemy:第2节:查询条件设置 SQLAlchemy是Python编程语言下的一款开源软件。提供了SQL工具包及对象关系...

    noONE 评论0 收藏0
  • Flask扩展之flask-sqlalchemy(上)

    摘要:查询记录在调试或测试模式自动启用。可以用于显式禁用原生支持。当使用不合适的指定无编码的数据库默认值时,这对于一些数据库适配器是必须的比如上某些版本的。这对是必要的,它默认移除闲置多于小时的连接。注意如果使用了,自动设定这个值为小时。 flask-sqlalchemy是flask的一个ORM扩展框架,这个扩展在sqlalchemy的进行的扩展,更方便的结合Flask.什么是ORM?其是O...

    KaltZK 评论0 收藏0
  • Python-SQLAlchemy:第3节:关系操作

    摘要:本节围绕在中如何定义关系及如何使用关系进行查询进行讲解,使读者能够快速掌握的关系操作。班级与学生为一对多关系,班级与老师之间为多对多关系。三年二班多对多关系的使用通过关联模型实现,在其中分别设置模型和的外键,并且在父模型中设置相应的实现。 上一篇文章:Python-SQLAlchemy:第2节:查询条件设置下一篇文章:Python-SQLAlchemy:第4节:级联 关系数据库是建立...

    William_Sang 评论0 收藏0

发表评论

0条评论

dendoink

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<