Flask-SQLAlchemy 中的 relationship & backref

2023-05-16

 

今天重看 Flask 时,发现对backref仍然没有理解透彻。查阅文档后发现,以前试图孤立地理解backref是问题之源,backref是与relationship配合使用的。

一对多关系

db.relationship()用于在两个表之间建立一对多关系。例如书中 roles 表中一个 User 角色,可以对应 users 表中多个实际的普通用户。实现这种关系时,要在“多”这一侧加入一个外键,指向“一”这一侧联接的记录。

class Role(db.Model):

# ...

users = db.relationship('User', backref='role')

class User(db.Model):

# ...

role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

relationship & ForeighKey

大多数情况下, db.relationship() 都能自行找到关系中的外键, 但有时却无法决定把 哪一列作为外键。 例如, 如果 User 模型中有两个或以上的列定义为 Role 模型的外键, SQLAlchemy 就不知道该使用哪列。如果无法决定外键,你就要为 db.relationship() 提供额外参数,从而确定所用外键。(见书 P49)

relationship & backref

通过db.relationship(),Role 模型有了一个可以获得对应角色所有用户的属性users。默认是列表形式,lazy='dynamic'时返回的是一个 query 对象。即relationship提供了 Role 对 User 的访问。

backref正好相反,提供了 User 对 Role 的访问。

不妨设一个 Role 实例为 user_role,一个 User 实例为 u。relationship 使 user_role.users 可以访问所有符合角色的用户,而 backref 使 u.role 可以获得用户对应的角色。

示例



$ p manage.py shell

>>> user_role = Role.query.filter_by(name='User').all()

>>> user_role

[<Role u'User'>]

>>> user_role = Role.query.filter_by(name='User').first()

>>> user_role

<Role u'User'>

>>> user_role.users

<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x1087c1050>

>>> user_role.users.order_by(User.username).all()

[<User u'alice78'>, <User u'andrea86'>, <User u'hmr'>]

>>> Role.query.all()

[<Role u'Moderator'>, <Role u'Administrator'>, <Role u'User'>]

>>> user_role.users.count()

3

>>> u = User.query.filter_by(username='hmr').first()

>>> u

<User u'hmr'>

>>> u.role

<Role u'User'>

 

一对一关系

除了一对多之外, 还有几种其他的关系类型。一对一关系可以用前面介绍的一对多关系表示, 但调用 db.relationship() 时要把 uselist 设为 False , 把“多”变成“一”。

多对多关系

如果你想要用多对多关系,你需要定义一个用于关系的辅助表。对于这个辅助表, 强烈建议  使用模型,而是采用一个实际的表:

tags = db.Table('tags',
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
    db.Column('page_id', db.Integer, db.ForeignKey('page.id'))
)

class Page(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    tags = db.relationship('Tag', secondary=tags,
        backref=db.backref('pages', lazy='dynamic'))

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)

这里我们配置 Page.tags 加载后作为标签的列表,因为我们并不期望每页出现 太多的标签。而每个 tag 的页面列表( Tag.pages )是一个动态的反向引用。 正如上面提到的,这意味着你会得到一个可以发起 select 的查询对象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flask-SQLAlchemy 中的 relationship & backref 的相关文章

随机推荐

  • vscode终端不显示,闪退问题解决(完整步骤)

    1 以管理员身份运行此程序 步骤 xff1a 1 1 找到该文件目录的文件图标 1 2 右键属性选择兼容性 1 3 选择更改所有用户的设置然后勾选以管理员身份运行此程序后重新打开vscode 2 在vscode修改配置文件 2 1 打开vs
  • Vue项目启动报错 error:cannot find module xxx

    原因 xff1a 无法找到项目依赖的某个模块 解决办法 xff1a 1 删掉存放模块的文件夹node module xff1b 2 执行清除缓存命令 npm cache clean xff1b 如果报错 xff0c 使用强制清除npm ca
  • OkHttp-(一)HttpUrl了解

    1 xff0c git地址 xff1a https github com square okhttp 2 xff0c 官网地址 xff1a https square github io okhttp Http作为现代应用程序的常用联网方式
  • 学习网络编程第一步,安装NetAssist网络调试助手

    x1f4d6 摘要 今天分享下 遇到 Request header is too large xff0c 如何解决 xff0c 欢迎关注 xff01 x1f91e 简单介绍 NetAssist 是一款免安装的网络调试助手工具 今天给大家带来
  • 初学STM32之串口通信

    文章目录 一 背景知识1 处理器与外部通信的两种方式2 串行通信的三种传输方式3 串行通信的通信方式 二 串口通信基础1 STM32的串口通信接口2 UART异步通信引脚连接方法3 UART异步通信方式特点4 串口异步通信需要定义的参数 三
  • 前端架构图解

  • Ubuntu 18.04快捷安装ROS Melodic及rosdep update time out的问题解决

    1 ROS快捷安装 以下安装指令汇总针对Ubuntu18 04的ROS Melodic版本 xff1a 强烈建议复制以下指令到新建的xxx sh文件中 xff0c 保存后给xxx sh权限 xff0c 然后执行脚本一路输入y等候安装完成 e
  • NVIDIA Jetson AGX Xavier学习笔记3——环境配置(pytorch、torchvision、cv2)

    最近研究中需要使用NVIDIA Jetson AGX Xavier人工智能开发组件 由于也是第一次接触相关硬件设备 xff0c 遇到了很多困难 在这里记录整个Jetson AGX Xavier组件的学习过程 其中很多内容网上有比较详细的教程
  • Linux网络编程——tcp实例

    题目 1 通过TCP协议实现多个client端可以并发连接到server xff0c client可获得server指定目录下的文件列表 span class hljs comment client c Created on 2016年11
  • A星寻路算法的学习总结(详解)

    目录 1 理论基础 1 1A星寻路是用来解决什么问题的 1 2A星寻路的基本原理 2 代码实现 2 1每个格子的信息 2 2A星寻路管理器 2 3测试代码 3 实例演示 1 理论基础 1 1A星寻路是用来解决什么问题的 A星寻路是用来计算玩
  • C语言单片机栈、堆、堆栈的区别(仅供参考)

    计算机C语言中各个变量的存放区域 xff1a 代码区 xff08 CODE xff09 xff1a 存放函数代码 xff1b 静态数据区 xff08 DATA xff09 xff1a 存放全局变量 静态变量 xff1b 堆区 xff08 H
  • 用c语言写链表

    链表是数据结构的一种 xff0c 是其他三个数据结构栈 xff0c 树 xff0c 图的基础 xff0c 只有将链表这一数据结构弄懂 xff0c 才能理解其他三种数据结构 举一个例子 xff0c 老师让你设计一个联系人系统 xff0c 其中
  • Fiddler抓包工具详解

    Fiddler的详细介绍 一 Fiddler与其他抓包工具的区别 1 Firebug虽然可以抓包 xff0c 但是对于分析http请求的详细信息 xff0c 不够强大 模拟http请求的功能也不够 xff0c 且firebug常常是需要 无
  • python 解析Json对象之jsonpath_rw用法

    jsonpath rw xff1a 一个可以像写xpath一样写json的Python第三方库 首先安装 xff1a pip install jsonpath rw 实例 xff1a from jsonpath rw import json
  • selenium之xpath使用

    XPath即XML路径语言 xff0c 支持从xml或html中查找元素节点 xff0c 使用XPath完全可以替代其他定位放式 xff0c 如 xff1a find element by xpath 39 64 id 61 34 34 3
  • Python-面向对象之多态

    当子类和父类都存在相同的run 方法时 xff0c 我们说 xff0c 子类的run 覆盖了父类的run xff0c 在代码运行的时候 xff0c 总是会调用子类的run 这样 xff0c 我们就获得了继承的另一个好处 xff1a 多态 c
  • 使用Ubuntu帐户创建SFTP

    提供sftp服务的有vsftpd和internal sftp xff0c 这里用的是系统自带的internal sftp xff0c 操作步骤如下 xff1a 1 创建用户 testenv xff0c 并禁止ssh登录 xff0c 不创建家
  • flask数据分页paginate的使用(flask学习)

    Flask的数据分页示例 1 xff0c 首先写数据获取的视图函数 xff0c 就像这样 xff1a 64 app route 39 39 64 login required def index page 61 request args g
  • Python __dict__属性详解

    我们都知道Python一切皆对象 xff0c 那么Python究竟是怎么管理对象的呢 xff1f 1 无处不在的 dict 首先看一下类的 dict 属性和类对象的 dict 属性 coding utf 8 class A object 3
  • Flask-SQLAlchemy 中的 relationship & backref

    今天重看 Flask 时 xff0c 发现对backref仍然没有理解透彻 查阅文档后发现 xff0c 以前试图孤立地理解backref是问题之源 xff0c backref是与relationship配合使用的 一对多关系 db rela