peewee:从多对多关系中筛选选择查询结果

2024-09-28 01:32:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码

#!/usr/bin/env python

"""doc"""

import peewee

db = peewee.SqliteDatabase(":memory:")


class BaseModel(peewee.Model):  # pylint: disable=W0232
    """base model"""

    class Meta:  # pylint: disable=C0111,W0232,R0903
        database = db


class Student(BaseModel):
    """doc"""
    name = peewee.CharField()


class Course(BaseModel):
    """doc"""
    name = peewee.CharField()


class StudentCourse(BaseModel):
    """doc"""
    student = peewee.ForeignKeyField(Student)
    course = peewee.ForeignKeyField(Course)

Student.create_table()
Course.create_table()
StudentCourse.create_table()

s1 = Student(name="Student1")
s1.save()
s2 = Student(name="Student2")
s2.save()
s3 = Student(name="Student3")
s3.save()
s4 = Student(name="Student4")
s4.save()
c1 = Course(name="course1")
c1.save()
c2 = Course(name="course2")
c2.save()
c3 = Course(name="course3")
c3.save()
sc21 = StudentCourse(student=s2, course=c1)
sc21.save()
sc22 = StudentCourse(student=s2, course=c2)
sc22.save()
sc23 = StudentCourse(student=s2, course=c3)
sc23.save()
sc31 = StudentCourse(student=s3, course=c1)
sc31.save()
sc32 = StudentCourse(student=s3, course=c2)
sc32.save()
sc41 = StudentCourse(student=s4, course=c1)
sc41.save()

query = (
    StudentCourse
    .select(StudentCourse, Student, Course)
    .join(Course)
    .switch(StudentCourse)
    .join(Student)
    .order_by(Student.name))

last = None
for student_course in query:
    student = student_course.student
    if student != last:
        last = student
        print "Student: %s" % student.name
    print "    - %s" % student_course.course.name

产生这个输出:

^{pr2}$

这基本上是peewee docs中的示例

我需要过滤结果并只从给定子集中选择那些拥有所有课程的学生:

courses = ["course1", "course2"]

我曾尝试使用IN运算符,并将select查询修改为如下所示:

    query = (
    StudentCourse
    .select(StudentCourse, Student, Course)
    .join(Course)
    .switch(StudentCourse)
    .join(Student)
    .where(Course.name << courses)
    .order_by(Student.name))

但它产生了一个错误的结果,这意味着我做错了:

Student: Student2
    - course1
    - course2
Student: Student3
    - course1
    - course2
Student: Student4
    - course1

这里有两个错误:

  1. 学生2的课程3没有打印,我需要。我想这是因为课程3不在课程列表中。在
  2. 学生4被选中,但不应该被选中,因为学生4没有课程1课程2,然而课程1课程列表中。在

有没有可能只在一个查询中实现我想要的结果,或者我必须遍历学生,为每个学生进行一个选择查询,并根据我的课程过滤器匹配他们的课程列表?在

我的目标是获得以下输出:

Student: Student2
    - course1
    - course2
    - course3
Student: Student3
    - course1
    - course2

Tags: namesavestudent学生class课程peewees2

热门问题