SQLAlchemy 与 fask-SQLAlchemy 中的多表查询例子

我们知道,<学生、课程、选课>,是一个典型的多对多关系。
现分别用 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

时间: 2024-12-21 23:33:55

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

.net mvc 中如何多表查询数据

问题描述 Strong.IBLL.ISysUserService_userService=newSysUserService();publicActionResultGetAllUserInfos(){intpageIndex=Request["page"]==null?1:int.Parse(Request["page"]);intpageSize=Request["rows"]==null?10:int.Parse(Request["

thinkphp多表查询

在学习thinkphp 的过程中,需要对多表进行操作,但是在实际过程中,总是遇到各种问题,所以写下这篇博文,作为自己的学习历程   在操作过程中,两表查询都没有问题,但是三表查询就开始出现问题   有以下三张表,分表为pl表(uid,content),user表(id,username),lyb表(uid,title)   多表查询操作有以下几种方法:   ㈠视图模型(推荐)   定义视图模型,只需要继承Think\Model\ViewModel,然后设置viewFields属性即可   复制代

SQL多表查询详解

本教程为大家介绍SQL中的多表查询,下面我们来看看具体实例吧. 新建两张表: 表1:student 截图如下: 表2:course 截图如下: (此时这样建表只是为了演示连接SQL语句,当然实际开发中我们不会这样建表,实际开发中这两个表会有自己不同的主键.) 一.外连接 外连接可分为:左连接.右连接.完全外连接. 1.左连接 left join 或 left outer join SQL语句:select * from student left join course on student.ID

数据库多表查询分页问题

问题描述 数据库多表查询分页问题 一张图片表和一张图书表,一本图书对应多张图片,我在两个表连接查询的时候,假设 一个图书对应3张图片,则就会出查询出3条记录,但在分页的时候就会出现问题,limit 0,1 ,就只显示一条记录,但我是想得到一条记录,其中包含3张图片,该怎么解决 解决方案 http://wenku.baidu.com/link?url=bbY7mfRa9_OJxzbeMZ1jUj1GdNVtRXgMsZKsKVPTCJy5FqHkY6U2EPz5sLAZnqmaWKpIP1XiHV

thinkphp学习笔记之多表查询_php实例

在操作过程中,两表查询都没有问题,但是三表查询就开始出现问题 有以下三张表,分表为pl表(uid,content),user表(id,username),lyb表(uid,title) 多表查询操作有以下几种方法: ㈠视图模型(推荐) 定义视图模型,只需要继承Think\Model\ViewModel,然后设置viewFields属性即可 public $viewFields = array( 'pl' =>array('uid','rid','content'), 'user' =>arra

详解Yii2.0使用AR联表查询实例

Yii2.0中使用联表查询有两种办法,第一种是查询构建器(Query Builder),第二种使用活动记录(Active Record),中文网对查询构建器讲的很详细,AR则说的很坑爹,下面贴出自己实践的方法,以供参考. 两个表 {{%article}} 和 {{%article_class}} {{%article}} .article_class关联{{%article_class}}.id 1.要使用AR做关联查询,首先在models {Article} 中创建关联: class Arti

40-.net如何从数据库中的一个表中取值

问题描述 .net如何从数据库中的一个表中取值 假设这是我数据库里的一张表(数据库是oracle),我该如何取得这些数将他们传给jsonObj.Rows,求教各位大神,能给个具体的实现过程吗? 解决方案 sonObj.Rows是你自己组装的json对象吧,你首先要查询数据库,这个自己看msdn把,很简单,获取值后开始组织json就行了 解决方案二: 自己读取数据后,通过服务器端代码赋值给aspx上的script标签就行,注意<%%>这种代码不能放js文件里面,必须是在aspx页面里面才能解析运

金山wps文档中的工作表单独怎么设置密码

  在金山wps文档的编辑中,不少网友都会插入数据表格,方便用户理解.不过,一些网友担心表格内的数据会被篡改,因此会把整个文档设置密码.不过,您可以按照下面的方法,设置成:在WPS文字插入的表格不让修改,只能修改表格外的文字.下面就来看看具体的教程吧! 保护工作表 金山wps文档中的工作表设置密码的方法: 1.在文字需要插入表格的地方点"插入"菜单,选下拉列表中的对象. 2.在选"新建"--"WPS表格 工作簿",确定. 3.系统自动打开ET工作

ADO.NET中的多数据表操作浅析之读取

ado|数据 在开发基于.NET平台的数据库应用程序时,我们一般都会用到DataSet,作为ADO.NET的核心类它为我们提供了强大的功能,而整个看上去就像是放在内存内的一个小型数据库,内部包括了DataTable.DataView.DataRow.DataColumn.Constraint以及DataRelation.当初看到它时真的是有点兴奋. 下面根据我的一些经验来举例说明在ADO.NET中的多表填充.关联表更新以及多个Command对象执行过程中启用事务的操作.欢迎大家交流,或在Blog