Python 如何让棉花糖Sqlalchemy按关联对象字段排序?

Python 如何让棉花糖Sqlalchemy按关联对象字段排序?,python,flask-sqlalchemy,marshmallow,marshmallow-sqlalchemy,Python,Flask Sqlalchemy,Marshmallow,Marshmallow Sqlalchemy,如何让棉花糖按关联对象(seat_index)中的字段对返回的数据集进行排序最终结果是按上课开始时间,然后按学生座位指数对一组教室对象进行排序 我正在寻找与下面的非工作代码等效的东西 query = Classroom.query.filter().order_by(Classroom.start_time, ClassStuAssocObj.seat_index).all() data = ClassroomSchema(many=True).dump(query) 只有使用SQLalch

如何让棉花糖按关联对象(seat_index)中的字段对返回的数据集进行排序
最终结果是按上课开始时间,然后按学生座位指数对一组教室对象进行排序

我正在寻找与下面的非工作代码等效的东西

query = Classroom.query.filter().order_by(Classroom.start_time, ClassStuAssocObj.seat_index).all()
data = ClassroomSchema(many=True).dump(query)

只有使用SQLalchemy,我才能创建一个工作查询–使用seat_索引进行排序)


使用棉花糖和SqlAlchemy,我可以按字段(开始时间)订购\u——只要字段在教室模型内

query = Classroom.query.filter().order_by(desc('start_time')).all()
data = ClassroomSchema(many=True).dump(query)

问题–我不确定如何在排序中包含关联对象的seat_索引字段。
任何朝着正确方向的努力都是值得赞赏的——因为我对棉花糖还不熟悉


参考代码缩写

app = create_app()
app.app_context().push()
db.create_all()

data = ClassroomSchema(many=True).dump(Classroom.query.all())
pprint(data, indent=2)
db.session.close()
输出

[ { 'course': { 
                'lesson': 10,
                'level': 20,
                'topic': 'My favorite Giraffe',
                'unit': 30},
    'start_time': '2020-02-10T06:00:00',
    'students': [ OrderedDict([ ('seat_index', 1),
                                ( 'student',
                                  { 'age': 8,
                                    'gender': 'M',
                                    'student_name': 'Billy'})]),
                  OrderedDict([ ('seat_index', 3),
                                ( 'student',
                                  { 'age': 9,
                                    'gender': 'F',
                                    'student_name': 'Jacky'})]),
                  OrderedDict([ ('seat_index', 2),
                                ( 'student',
                                  { 'age': 7,
                                    'student_name': 'Dora'})]),
                  OrderedDict([ ('seat_index', 4),
                                ( 'student',
                                  { 'age': 7,
                                    'gender': 'A',
'student_name': 'Cici'})])]},
schema.py

from flask_marshmallow import Marshmallow
from marshmallow import Schema, fields, pprint

ma = Marshmallow()


class StudentSchema(ma.Schema):
    class Meta:
        fields = ('student_id', 'student_name', 'gender', 'age')
        # ordered = True


class ClassStuSchema(Schema):
    class Meta:
        ordered = True
        fields = ('seat_index', 'student')

    student = fields.Nested(StudentSchema)


class CourseSchema(ma.Schema):
    class Meta:
        fields = ('course_id', 'topic', 'level', 'unit', 'lesson','classroom')
        # ordered = True


class ClassroomSchema(ma.Schema):
    course = fields.Nested(CourseSchema, many=False)
    students = fields.Nested(ClassStuSchema, many=True)

    class Meta:
        fields = ('id', 'start_time', 'course', 'students',)
        # ordered = True
model.py

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.dialects import postgresql

db = SQLAlchemy()

class ClassStuAssocObj(db.Model):
    __tablename__ = 'class_stu_assoc_obj'
    classroom_id = db.Column(db.Integer, db.ForeignKey('classroom.classroom_id'), primary_key=True )
    student_id = db.Column(db.Integer, db.ForeignKey('student.student_id'),  primary_key=True)
    classroom = db.relationship('Classroom', uselist=False, back_populates='students')
    student = db.relationship('Student', uselist=False)
    seat_index = db.Column(db.Integer) # extra data for association object

    def __repr__(self):
        return f'<ClassStuAssocObj {self.classroom.created_date}, {self.student.student_name},' \
               f' seat_index: {self.seat_index}>'


class Classroom(db.Model):
    __tablename__ = 'classroom'
    classroom_id = db.Column(db.Integer, primary_key=True)
    start_time = db.Column(db.DateTime)

    course_id = db.Column(db.Integer, db.ForeignKey('course.course_id'))
    course = db.relationship("Course", back_populates='classrooms')

    student = db.relationship('ClassStuAssocObj')
    students = db.relationship('ClassStuAssocObj', back_populates='classroom')


    def __init__(self, start_time):
        self.start_time = start_time

    def __repr__(self):
        return f'<Classroom {self.start_time}>'


class Course(db.Model):
    __tablename__ = 'course'
    topic = db.Column(db.String(100)) 
    course_name = db.Column(db.String(100))
    level = db.Column(db.Integer)
    unit = db.Column(db.Integer)
    lesson = db.Column(db.Integer)
    classrooms = db.relationship("Classroom", back_populates="course")


    def __init__(self, topic, course_name, level, unit, lesso):
        self.topic = topic
        self.course_name = course_name
        self.level = level
        self.unit = unit
        self.lesson = lesson


    def __repr__(self):
        return f'<Course {self.topic}, {self.course_name}, >'


class Student(db.Model):
    __tablename__ = 'student'
    student_id = db.Column(db.Integer, primary_key=True)
    student_name = db.Column(db.String(140))
    gender = db.Column(db.String(140))
    age = db.Column(db.Integer)


    classroom = db.relationship('ClassStuAssocObj')

    def __init__(self, student_id, student_name, gender, age):
        self.student_id = student_id
        self.student_name = student_name
        self.gender = gender
        self.age = age

    def __repr__(self):
        return f'<Student {self.student_id}, {self.student_name}, {self.gender}, {self.age}>'

我能让它工作的唯一方法是对棉花糖堆后的巢状田野进行分类。也许,随着更多的时间和经验(棉花糖),一种更优雅的方式将会出现

def sort_students(data, field, ascending=True):
    reverse_bool = False if ascending else True
    for cr in data:
        cr['students'].sort(key=lambda x: x[field], reverse=reverse_bool)  # Sort in place
    return data

query = Classroom.query.filter().order_by('start_time').all()
data = ClassroomSchema(many=True).dump(query)
data = sort_students(data, 'seat_index')
pprint(data, indent=2)

您可以使用“order_by”直接在SQL Alchemy模型中设置关联对象的排序。下面是从中复制和粘贴的

from sqlalchemy.engine.url import URL
from config import DB
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


def create_app():
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = URL(**DB['LOCAL'])
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    db.init_app(app)
    return app
def sort_students(data, field, ascending=True):
    reverse_bool = False if ascending else True
    for cr in data:
        cr['students'].sort(key=lambda x: x[field], reverse=reverse_bool)  # Sort in place
    return data

query = Classroom.query.filter().order_by('start_time').all()
data = ClassroomSchema(many=True).dump(query)
data = sort_students(data, 'seat_index')
pprint(data, indent=2)
class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    children = relationship("Child", order_by="Child.id")