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

简介: 我们知道,,是一个典型的多对多关系。现分别用 SQLAlchemy 与 fask-SQLAlchemy 实现。声明:本人实测通过。使用 SQLAlchemyfrom sqlalchemy import Table, Column, Integer, String, ForeignKeyfrom sqlalchemy.orm import relationship, backreffrom sqlalchemy.ext.declarative import declarative_baseBase = declarative_base()# 下表是用于关系的辅助表。

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

目录
相关文章
|
开发工具 对象存储 Python
使用Python的SDK从OSS中下载指定日期的所有文件
使用Python的SDK从OSS中下载指定日期的所有文件
578 1
|
12月前
|
算法
鬼手操控着你的手机?大模型GUI智能体易遭受环境劫持
【9月更文挑战第27天】近年来,随着人工智能技术的发展,多模态大语言模型(MLLM)在图形用户界面(GUI)中广泛应用,提升了交互体验。然而,最新研究《环境警示:多模态智能体易受环境干扰》指出,这些智能体可能因环境干扰而行为失准。作者通过实验展示了即使是强大模型也会受无关因素影响,导致不可靠或不可预测的行为。研究还证实,通过环境注入攻击可进一步加剧此问题。尽管如此,多模态GUI智能体依然潜力巨大,未来需改进感知能力和算法以增强鲁棒性,解决环境干扰问题。论文详细内容见:https://arxiv.org/abs/2408.02544。
164 8
|
10月前
|
UED 开发者 容器
鸿蒙next版开发:ArkTS组件通用属性(背景设置)
在HarmonyOS 5.0中,ArkTS提供了多种背景设置属性,如backgroundColor、backgroundImage、backgroundSize、backgroundPosition和backgroundBlurStyle,允许开发者自定义组件的背景样式,提升应用的视觉效果和用户体验。本文详细解读了这些属性,并提供了示例代码进行说明。
989 5
|
11月前
|
人工智能 监控 API
window本地部署Dify
这篇文章详细介绍了如何在Windows系统上本地部署Dify平台,并通过Docker进行环境搭建,实现基于大模型的AI应用开发和管理。
4380 1
window本地部署Dify
|
12月前
|
JavaScript 数据库 Python
一篇文章搞懂flask_sqlalchemy常用操作
这篇文章介绍了Flask框架中SQLAlchemy库的常用操作,包括查询、删除和更新数据的方法和技巧。
625 3
|
NoSQL Redis Python
python flask 使用 redis 写一个例子给我
python flask 使用 redis 写一个例子给我
352 4
|
安全 数据库连接 数据库
Flask数据库操作实战:增删改查一网打尽
【4月更文挑战第15天】本文介绍了在Flask中进行数据库操作的方法,包括选择数据库扩展(如Flask-SQLAlchemy)、配置数据库、定义模型以及执行CRUD操作。通过Flask-SQLAlchemy的ORM功能,开发者可以方便地管理数据库表和记录。文章详细展示了如何创建模型、添加、查询、更新和删除数据,并提到了高级查询和关系映射。此外,还提及了数据库迁移工具Flask-Migrate以及性能优化和安全性问题。了解这些基础,有助于开发者构建高效、安全的Flask Web应用。
|
存储 安全 算法
Flask用户认证与权限管理实战
【4月更文挑战第16天】在Flask Web开发中,用户认证和权限管理是保障安全的关键。本文介绍了实现这一目标的最佳实践:1) 设计用户模型,使用SQLAlchemy存储用户信息;2) 通过密码哈希确保密码安全,使用`werkzeug.security`进行哈希和验证;3) 实现登录功能,借助Flask-Login处理登录和登出;4) 进行权限管理,定义角色和权限模型,用装饰器或函数检查用户权限。通过这些方法,开发者能有效地控制用户访问,提升应用安全性。
1192 0
|
关系型数据库 MySQL 数据库
SQLAlchemy关联表一对多关系的详解
SQLAlchemy关联表一对多关系的详解
|
API Python
flask 生成swagger文档
flask 生成swagger文档
453 0