20201102-第十讲-flask框架

SQLAlchemy-ORM

1. MVT

M model 模型

V view 视图

T template 模板

客户端请求---》view----》model-----》view----》template--->view----->客户端

查数据 渲染

2. Flask表关系-一对一

addresses = relationship("Address", backref='addresses', uselist=False)

一对一其实是一对多的特殊情况,从一对多的是实例发现,一对应的是User表,而多对应的是address,也就是说一个User对象有多个address。

class User(Base):

    __tablename__ = 'users'

    id = Column(Integer,primary_key=True)

    name = Column(String(50))

    fullname = Column(String(50))

    password = Column(String(100))

    addresses = relationship("Address",backref='addresses',uselist=False)


class Address(Base):

    __tablename__ = 'addresses'

    id = Column(Integer,primary_key=True)

    email_address = Column(String(50))

    user_id = Column(Integer,ForeignKey('users.id')

    user = relationship('Address',backref='user')


3. flask表关系-多对多

# 创建中间表格

teacher_classes = Table(

      'teacher_classes',

      Base.metadata,

      Column('teacher_id', Integer, ForeignKey('teacher.id')),

      Column('classes_id', Integer, ForeignKey('classes.id'))

)

# 模型中

classes = relationship('Classes', backref='teachers', secondary=teacher_classes)

多对多需要一个中间来作为连接,同理在slalchemy中的orm也需要一个中间表,假如现在有一个Teacher和一个Classes表,即老师和班级,一个老师可以教多个班级,一个班级有多个老师,是一种典型的多对多关系,那么通过sqlalchemy的ORM的实现方式

1.association_table = Table(

 2.       'teacher_classes',

3.        Base.metadata,

4.        Column('teacher_id',Integer,ForeignKey('teacher.id')),

5.        Column('classes_id',Integer,ForeignKey('classes.id'))

6.  )

7.

8.class Teacher(Base):

 9.       __tablename__ = 'teacher'

10.      id = Column(Integer,primary_key=True)

11.      tno = Column(String(10))

12.      name = Column(String(50))

13.      age = Column(Integer)

14.      classes = relationship('Classes',secondary=association_table,backref='teachers')

15.

16.class Classes(Base):

 17.       __tablename__ = 'classes'

 18.       id = Column(Integer,primary_key=True)

 19.       cno = Column(String(10))

 20.       name = Column(String(50))

 21.      teachers = relationship('Teacher',secondary=association_table,backref='classes')

要创建一个多对多的关系表,首先需要一个中间表,通过Table来创建一个中间表。上例中间第一个参数teacher_classes代表的是中间表,第二个参数是Base的元素,第三个和第四个参数就是要连接的二个表,其中Column第一个参数是表示的是连接表的外键名,第二个参数表示这个外键的类型,第三个参数表示要外键的表名和字段。

4. 数据库排序

1、order_by:可指定根据这个表中的某个字段进行排序,如在前面加一个-,代表的是降序排序。

2、在模型定义的时候指定默认排序:有些时候,不想每次在查询的时都指定排序的方式,可以在定义模型时指定排序的方式。

在模型定义中,添加以下代码

1. __mapper_args__ = {

2.      "order_by": title

3. }

。即可让文章使用标题来进行排序。

3.正向排序和反向排序:默认情况是从小到大,从前到后排序的,如想要反向排序,可以调用排序的字段desc方法。

。limit 限制查询条数

。limit:可限制每次查询时只查几条数据。

。offset:可限制查找数据时过滤掉前面多少条。 从哪里开始(类似于索引)

。切片:可对Query对象使用切片操作,来获取想要的数据。(和数据类型切片一样)

5. 高级查询和子查询

group_by 进行分组 通常和聚合函数配合使用。根据某个字段进行分组。比如想要根据性别进行分组,来统计每个分组分别有多少人

1.session.query(User.gender,func.count(User.id)).group_by(User.gender).all()

having 新查询之后的数据集还想通过限制条件来查询,就需要用到having来做限制。

having是对查找结果进一步过滤。比如只想要看未成年人的数量,那么可以首先对年龄进行分组统计人数,延后再对分组进行having过滤。

1.result = session.query(User.age,func.count(User.id)).group_by(User.age).having(User.age >= 18).all()

join方法

join查询分为二种,一种是inner join,默认的是inner join。另一种是Outer join。默认的是inner join,如果指定left join 或者是right join则为outer join。如果想要查询User及其对应的Address,则可以通过以下方式来实现

1. for u,a in session.query(User,Address).filter(User.id==Address.user_id).all():

 2.      print(u)

3.        print(a)

如果采用outer join,可以获取所有user,而不用在乎这个user是否有address对象,并且outer join默认为左外查询:

1. for instance in session.query(User,Address).outerjoin(Address).all():

2.      print(instance)

别名: 

当多表查询时,有时同一个表要用到多次,这时用别名就可以方便解决命名冲突的问题了:

1 from sqlalchemy.orm import aliased

2 adalias1 = aliased(Address)

3 adalias2 = aliased(Address)

4 for username,email1,email2 in session.query(User.name,adalias1.email_address,adalias2.email_address).join(adalias1).join(adalias2).all():

 5     print(username,email1,email2)

子查询

sqlachemy 也支持子查询,如现在要查找一个用户的用户名及该用户的邮箱地址数量。要满足这个需求,可以在子查询中找到所有用户的邮箱数(通过group by合并同一用户),然后再将结果放在父查询中进行使用:

1 from sqlalchemy.sql import func

2 # 构造子查询

3 stmt = session.query(Address.user_id.label('user_id'),func.count(*).label('address_count')).group_by(Address.user_id).subquery()

4 # 将子查询放到父查询中

5 for u,count in session.query(User,stmt.c.address_count).outerjoin(stmt,User.id==stmt.c.user_id).order_by(User.id):

 6     print u,count

从上面看到,一个查询如果想要变成子查询,则是通过subquery()方法实现,变成子查询后,通过子查询.c属性来访问查询出来的列。以上方法只能查询某个对象的具体字段,如要查找整个实体,则想需要通过aliased方法

1 stmt = session.query(Address)

2 adalias = aliased(Address,stmt)

3 for user,address in session.query(User,stmt).join(stmt,User.addresses):

4 print user,address

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容

  • 1. SQLALchemy 1.1 SQLAlchemy介绍 数据库是一个网站的基础,在Flask中可以自由的使用...
    成长之路丶阅读 492评论 0 0
  • 声明映射 现在我们有了一个base, 我们可以从它派生任意多的映射类。 我们先从一个简单的users表开始。这张表...
    月生鄢阅读 521评论 0 0
  • 二、SQLAlchemy常用数据类型 &Column常用参数 通过字段给数据表中的数据添加指定数据类型 Colum...
    寻找u阅读 161评论 0 0
  • Python_SqlAlchemy [toc] 00简介说明 SQLAlchemy是Python编程语言下的一款O...
    SuperScfan阅读 1,455评论 0 0
  • SQLAlchemy是一个基于Python的ORM框架。该框架是建立在DB-API之上,使用关系对象映射进行数据库...
    SkTj阅读 334评论 0 0