sqlalchemy之relationship的使用

表关系设置外键必须是innodb引擎。外键约束一般有以下几项

  1. RESTRICT:父表数据被删除,会阻止删除。默认就是这一项。
  2. NO ACTION:在MySQL中,同RESTRICT。
  3. CASCADE:级联删除。
  4. SET NULL:父表数据被删除,子表数据会设置为NULL

一对多

在SQLAlchemy提供了一个relationship类,可以定义属性,在访问相关联的表的时候就直接可以通过属性访问。
一对多的情况下,通常将外键字段和设置在‘多’的表格中

uid = Column(Integer,ForeignKey('user.id')) #外键也是在表中多了一个字段
author = relationship("Users",backref="articles")#外键中定义relationship
user = session.query(Users).first()
print(user.articles) #User通过  backref 获取文章的信息 可能有多条信息
articles = session.query(Article).first()
print(articles.author)#查询‘多’中对应属性

一对一

不修改原表情况下,对该表在从表中增加字段,一对一链接

在从表模型中加字段以及relationship对象
id = Column(Integer,ForeignKey('user.id'))
user = relationship("Users",backref=backref("extends",uselist=False))#`uselist=False`引用从模型的时候,不再是列表,而是对象
user = session.query(Users).first()  #根据主查从表  这个和一对多类似
print(user.extends)
userextends = session.query(UsersExtend).first()
print(userextends.user)

多对多

  1. 多对多的关系需要通过一张中间表来绑定他们之间的关系。
  2. 先把两个需要做多对多的模型定义出来
  3. 使用Table定义一个中间表,中间表一般就是包含两个模型的外键字段就可以了,并且让他们两个来作为一个“复合主键”。
  4. 在两个需要做多对多的模型中随便选择一个模型,定义一个relationship属性,来绑定三者之间的关系,在使用relationship的时候,需要传入一个secondary=中间表。
article_tag = Table(#定义中间表
    'article_t',#建立表的名字
    Base.metadata,#
    Column('article_id',Integer,ForeignKey("article.id"),primary_key=True),#两个表的外键字段
    Column('tag_id',Integer,ForeignKey("tag.id"),primary_key=True),
)
#随便选择一个模型定义一个relationship,绑定他们三个之间的关系,需要传入article_tag(不是表名)作为中间表
articles = relationship("Article",backref="tags",secondary=article_tag)
#查询和之前的相似
article = session.query(Article).get(2)
print(article.tags)
tags = session.query(Tag).first()
print(tags.articles)

表关联时,关联数据的修改,可以通过relationship中的cascade参数设置以下的一些属性
5. save-update:默认选项。在添加一条数据的时候,会把其他和他相关联的数据都添加到数据库中。这种行为就是save-update属性影响的。
6. delete:表示当删除某一个模型中的数据的时候,是否也删掉使用relationship和他关联的数据。
7. delete-orphan:表示当对一个ORM对象解除了父表中的关联对象的时候,自己便会被删除掉。当然如果父表中的数据被删除,自己也会被删除。这个选项只能用在一对多上,不能用在多对多以及多对一上。并且还需要在子模型中的relationship中,增加一个single_parent=True的参数。
8. merge:默认选项。当在使用session.merge,合并一个对象的时候,会将使用了relationship相关联的对象也进行merge操作。
9. expunge:移除操作的时候,会将相关联的对象也进行移除。这个操作只是从session中移除,并不会真正的从数据库中删除。
10. all:是对save-update, merge, refresh-expire, expunge, delete几种的缩写。

定义模型的时候排序

    __mapper_args__ = {
        'order_by':create_time#默认是正序,前面加上-则是降序
    }

切片查询

#包头不包尾
session.query(Articles).order_by(Articles.create_time.desc())[0:2]#包头不包尾

懒加载:lazy=‘dynamic’,不再是一口气获取,可根据条件获取

 author = relationship("Users",backref=backref("articles",lazy='dynamic'))#添加懒加载属性
print(type(user.articles))#是一个AppenderQuery
print(user.articles) #是一个sql语句  而不是之前的一个文章的列表
article = user.articles.all()#通过实例化获取文章列表
print(article)
print(user.articles.filter(Articles.id>5).all()) #和上一条同理,获取query对象

subquery:子查询,提高查询性能

#lable相当于as 别名
dstmt=session.query(Users.city.label("城市"),Users.age.label("年龄")).filter(Users.username=='波老师').subquery()#生成子查询
result = session.query(Users).filter(Users.city==dstmt.c.城市,Users.age==dstmt.c.年龄).all()#调用子查询
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值