我们知道,<学生、课程、选课>,是一个典型的多对多关系。

现分别用 SQLAlchemy 与 fask-SQLAlchemy 实现。

声明:本人实测通过。

使用 SQLAlchemy

from sqlalchemy import Table, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() # 下表是用于关系的辅助表。对于这个辅助表, 强烈建议 不 使用模型,而是采用一个实际的表
# 此说法来源于:https://segmentfault.com/q/1010000003769460 # 选课表
sc = Table('sc', Base.metadata,
Column('sno', String(10), ForeignKey('student.sno')),
Column('cno', String(10), ForeignKey('course.cno'))
) # 学生表
class Student(Base):
__tablename__ = 'student'
sno = Column(String(10), primary_key=True)
sname = Column(String(10)) courses = relationship('Course',
secondary=sc,
backref=backref('student',lazy='dynamic'),
lazy='dynamic'
) def __repr__(self):
return "<Student(sno='%s', sname='%s')>" % (self.sno, self.sname) # 课程表
class Course(Base):
__tablename__ = 'course'
cno = Column(String(10), primary_key=True)
cname = Column(String(10), index=True) students = relationship('Student',
secondary=sc,
backref=backref('course',lazy='dynamic'),
lazy='dynamic'
) def __repr__(self):
return "<Course(cno='%s', cname='%s')>" % (self.cno, self.cname) from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker DB_CONNECT_STRING = 'sqlite://' # 'sqlite:///:memory:'
engine = create_engine(DB_CONNECT_STRING, echo=False)
DB_Session = sessionmaker(bind=engine)
session = DB_Session() # 1. 创建表(如果表已经存在,则不会创建)
Base.metadata.create_all(engine) # 2. 插入数据
# 不能这样:Student('201701', '张三')
some_students = [Student(sno='201701', sname='张三'),
Student(sno='201702', sname='李四'),
Student(sno='201703', sname='王五'),
Student(sno='201704', sname='赵六')]
session.add_all(some_students) some_courses = [Course(cno='#1', cname='C'),
Course(cno='#2', cname='C++'),
Course(cno='#3', cname='Java'),
Course(cno='#4', cname='Python')]
session.add_all(some_courses) session.execute(sc.insert().values(sno='201701', cno='#1'))
session.execute(sc.insert().values(sno='201701', cno='#4'))
session.execute(sc.insert().values(sno='201702', cno='#2'))
session.execute(sc.insert().values(sno='201703', cno='#3'))
session.execute(sc.insert().values(sno='201704', cno='#4')) session.commit() #查询
student = session.query(Student).filter_by(sname='张三').one()
courses = student.course.all() #该学生选择的所有课程
print(courses) course = session.query(Course).filter_by(cname='Python').one()
students = course.student.all() #选择该课程的所有学生
print(students)

使用 flask-SQLAlchemy

from flask import Flask
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app) # 学生-课程表(用于关系的辅助表。对于这个辅助表, 强烈建议 不 使用模型,而是采用一个实际的表)
sc = db.Table('sc',
db.Column('sno', db.String(10), db.ForeignKey('student.sno')),
db.Column('cno', db.String(10), db.ForeignKey('course.cno'))
) # 学生表
class Student(db.Model):
__tablename__ = 'student' sno = db.Column(db.String(10), primary_key=True)
sname = db.Column(db.String(10)) courses = db.relationship('Course',
secondary=sc,
backref=db.backref('student',lazy='dynamic'),
lazy='dynamic'
) def __init__(self, sno, sname):
self.sno = sno
self.sname = sname def __repr__(self):
return "<Student(sno='%s', sname='%s')>" % (self.sno, self.sname) # 课程表
class Course(db.Model):
__tablename__ = 'course' cno = db.Column(db.String(10), primary_key=True)
cname = db.Column(db.String(10), index=True) students = db.relationship('Student',
secondary=sc,
backref=db.backref('course',lazy='dynamic'),
lazy='dynamic'
) def __init__(self, cno, cname):
self.cno = cno
self.cname = cname def __repr__(self):
return "<Course(cno='%s', cname='%s')>" % (self.cno, self.cname) # 1. 创建表(如果表已经存在,则不会创建)
db.create_all() # 2. 插入数据
some_students = [Student('201701', '张三'),
Student('201702', '李四'),
Student('201703', '王五'),
Student('201704', '赵六')]
db.session.add_all(some_students) some_courses = [Course('#1', 'C'),
Course('#2', 'C++'),
Course('#3', 'Java'),
Course('#4', 'Python')]
db.session.add_all(some_courses) #scs = [sc(201701, 1), # 报错:"Table" object is not callable
# sc(201701, 4),
# sc(201702, 2),
# sc(201703, 3),
# sc(201704, 4)]
#db.session.add_all(scs) # 改正如下
db.session.execute(sc.insert().values(sno='201701', cno='#1'))
db.session.execute(sc.insert().values(sno='201701', cno='#4'))
db.session.execute(sc.insert().values(sno='201702', cno='#2'))
db.session.execute(sc.insert().values(sno='201703', cno='#3'))
db.session.execute(sc.insert().values(sno='201704', cno='#4')) db.session.commit() #查询
student = Student.query.filter_by(sname='张三').one()
courses = student.course.all() #该学生选择的所有课程
print(courses) course = Course.query.filter_by(cname='Python').one()
students = course.student.all() #选择该课程的所有学生
print(students)

感谢:

参考:https://segmentfault.com/q/1010000004567422

SQLAlchemy 与 fask-SQLAlchemy 中的多表查询例子的更多相关文章

  1. Hibernate中的多表查询及抓取策略

    1.Hibernate中的多表查询 1.1SQL中的多表查询 [交叉连接] select * from A,B; [内连接] 显示内连接:inner join(inner 可以省略) Select * ...

  2. mysql中的回表查询与索引覆盖

    了解一下MySQL中的回表查询与索引覆盖. 回表查询 要说回表查询,先要从InnoDB的索引实现说起.InnoDB有两大类索引,一类是聚集索引(Clustered Index),一类是普通索引(Sec ...

  3. mysql多表查询例子

    [理解方式]先分别找出每个表中查询出来的结果,然后再将两个结果合并. create database test charset utf8 collate utf8_bin;use test;creat ...

  4. Oracle中的多表查询

    多表查询 l 笛卡尔积: N*M l 使用关联字段消除笛卡尔积的多余数据: SELECT EMP.*,DEPT.DNAME,DEPT.LOC FROM EMP, DEPT WHERE EMP.DEPT ...

  5. Oracle中的多表查询(笛卡尔积原理)

    本次预计讲解的知识点 1. 多表查询的操作.限制.笛卡尔积的问题: 2. 统计函数及分组统计的操作: 3. 子查询的操作,并且结合限定查询.数据排序.多表查询.统计查询一起完成各个复杂查询的操作: 一 ...

  6. django中的跨表查询梳理

    1.前言 最近在写一个小项目,里面主要涉及的就是表与表之间复杂的关系.当真正开发起来的时候,才发现自己对复杂的表关系间的查询有点混乱,趁着这几天的时间,重新梳理了一下. 2.概念 在开始之前,先明确几 ...

  7. Django中的跨表查询,多表查询。

    一:Django中的ORM进行操作. 必须掌握的十三条: <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 & ...

  8. MyBatis中实现多表查询

    如果查询的数据量大,推荐使用N+1次查询.数据量少使用联合查询... 一. 1.Mybatis是实现多表查询方式 1.1  业务装配:对两个表编写单表查询语句,在业务(Service)把查询的两表结果 ...

  9. 在Mybatis中使用连表查询的一次实际应用

    以前在工作中很少使用多表关联查询,对连表查询的具体作用和使用场景也没有很直观的认识,通过这次在项目中的实际应用,对此有了一定的认识,特记录如下. 关联表介绍: 分别是属性表attr_info.属性值表 ...

随机推荐

  1. python 流程控制(for循环语句)

    1,for循环基本语法 2, for循环常用序列 3,for循环 else使用方法 1,for循环基本语法 for iterating_var in sequence: statements(s) 2 ...

  2. Saltstack安装配置过程

    一.安装配置 1.服务器配置情况 三台服务器,均需要关闭iptables和selinux(否则salt执行指令无效) master: 192.168.60.139 centos slave: 192. ...

  3. __MySQL 5.7 Replication 相关新功能说明

      背景: MySQL5.7在主从复制上面相对之前版本多了一些新特性,包括多源复制.基于组提交的并行复制.在线修改Replication Filter.GTID增强.半同步复制增强等.因为都是和复制相 ...

  4. Centos 6.5-yum安装出现错误解决方案

    最近在用Centos 6.5 的时候出现了以下情况: 遇到这种问题试试以下方法: 1.检查是否能上网:ping www.baidu.com 如果显示没有连接的话,就说明没网,也就无法使用yum 命令安 ...

  5. 虚拟机克隆linux centos 6.5 系统网卡配置

    作为一个刚刚接触linux系统的小白来说,VMware虚拟机安装好CentOS6.5系统后,纯净的系统多克隆几份出来方便后期做试验.克隆步骤很简单,克隆后出现的问题是克隆后的网卡MAC地址和原系统MA ...

  6. Linux运维之——每日小技巧,获取网站请求数的前20个IP

    获取网站请求书的前20个IP |grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20

  7. JFreeChart绘制XY折线图(工具类设计)

    准备用Java写通信的仿真平台作为毕业设计,相比matlab绘图,Java绘图需要自己去写很多工具类,博主在这采用了JFreeChart的开源解决方案,摸索着自己写了一个XY折线图工具类,话不多说贴源 ...

  8. JDK 环境变量 Windows配置

    安装完成JDK后需要配置环境变量,下面是环境变量的配置方法 1.配置环境变量: 对于Java程序开发而言,主要会使用JDK的两个命令:javac.exe.java.exe.路径:C:\Java\jdk ...

  9. node封装mysql操作

    前言 node是基于异步的,因此在进行数据库查询操作的通常是通过回调来操作查询结果.但是在有了es7的async/await,基本不再需要回调了,所以本篇是基于async/await对mysql进行一 ...

  10. PHPer是草根吗

    以下文字并没有非常多的技术词汇,所以只要对PHP感兴趣的人都可以看看. PHPer是草根吗? 从PHP诞生之日起,PHP就开始在Web应用方面为广大的程序员服务.同时,作为针对Web开发量身定制的脚本 ...