博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQLAlchemy Join Query 得到的不同数据行相同数据是同一个实例
阅读量:6324 次
发布时间:2019-06-22

本文共 1886 字,大约阅读时间需要 6 分钟。

在开发的时候遇到了一个很大的坑(还是因为是我不了解 SQLAlchemy 吧?), 记录一下免得往后再踩...

事情是这样的, 有三张表, 快速地模拟一下表结构:

student表|------+--------+----------+--------------||  id  +  name  +  gender  +  deleted_at  ||------+--------+----------+--------------|course表|------+---------+--------------+--------------||  id  +  title  +  teacher_id  +  deleted_at  ||------+---------+--------------+--------------|student_course_rel表|------+--------------+-------------+--------------||  id  |  student_id  +  course_id  +  deleted_at  ||------+--------------+-------------+--------------|复制代码

这里模拟了一个场景需求, 需要列出某位老师所教授的不同课程的学生列表, 并且要支持全量更新(更新的时候传入的列表为全部学生列表(新增和删除)) 这个时候我要 Join 三张表, 并且同一个学生对应的不同课程的 rel id 也得记录, 这样我就可以知道那些是新增的那些是删除的. 也就是说, 我需要将用户和课程的 rel id 进行绑定. 所以, 我就用这条语句进行 Query:

teacher_id = 'teacher_id'query_result = db.session.query(Course, Student, StudentCourseRel)\    .join(StudentCourseRel, Course.id == StudentCourseRel.course_id)\    .join(Student, StudentCourseRel.student_id == Student.id)\    .filter(Course.teacher_id == teacher_id, Course.deleted_at.is_(None),            Student.deleted_at.is_(None), StudentCourseRel.deleted_at.is_(None))\    .all()# query 出来的结果大致是这样的[(course_a, stu_1, rel_1), (course_a, stu_2, rel_2), (course_b, stu_1, rel_3), (course_c, stu_3, rel_4)]复制代码

这个时候, query 出来的结果确实是我想要的, 每个用户每个课程都会有一条记录. 列表没有任何问题. 但是在更新的时候就出 bug 了.

问题就出在student, course, rel_id绑定这一步用户. 和课程关系的绑定我是遍历数据列表, 并且将 rel id 作为 student 的一个属性.

# 处理数据result = set()for item in query_result:    course, student, rel = item    if course not in result:        course.students = []        result.add(container)    user.rel_id = rel.id    course.users.append(user)return result复制代码

就上例而言, SQLAlchemy 得到的数据中, course_a 所对应的 stu_1 和 course_b 所对应的 stu_1 是同一个实例, 也就是说在遍历并且进行赋值 rel_id 的时候, 后项会直接覆盖前项, 所以会造成数据的混乱.

这里就暴露出来一个点, 也就是说 SQLAlchemy 在处理 Join 后得到的同样数据是采用 同一个实例 对不同数据行进行拼接.

转载于:https://juejin.im/post/5c10ad9f6fb9a049fb43845e

你可能感兴趣的文章
android判断网络连接状态的三种方法
查看>>
ZOJ Monthly, March 2013 解题报告
查看>>
LaTex表格 Itemize&&enumerate
查看>>
Spring Boot中@OneToMany与@ManyToOne几个需要注意的问题
查看>>
文件传输协议之FTP
查看>>
Openstack 安装部署指南翻译系列 之 Glance服务安装(Image)
查看>>
Java 使用POI实现execl的导入导出数据实践
查看>>
Unity3D游戏开发之伤害数值显示
查看>>
如何在Linux上搭建一个基于Web的轻型监控系统
查看>>
linux基础命令使用
查看>>
zabbix简单检测
查看>>
other模块的网络请求业务封装工具类
查看>>
Windows进程崩溃问题定位方法
查看>>
程序员如何让自己 Be Cloud Native - 配置篇
查看>>
SQL Server各个版本之间的差异
查看>>
如何拆笔记本键盘(组图)
查看>>
lua install
查看>>
海量数据处理 算法总结
查看>>
mysql性能参数查询
查看>>
VirtualBox运行报错Unable to load R3 module
查看>>