class Parent(Base):
__tablename__ = 'parent'
id = Column(types.Integer, primary_key=True, autoincrement=True)
name = Column(types.Unicode, nullable=False)
class ParentFeature(Base):
__tablename__ = 'parent_feature'
id = Column(types.Integer, primary_key=True, autoincrement=True)
parent_id = Column(ForeignKey('parent.id', ondelete='CASCADE'), nullable=False, index=True)
parent = relationship('Parent')
unordered_things = relationship('Thing', secondary='parent_feature_thing')
things = relationship('Thing', secondary='parent_feature_thing', order_by=Thing.name, viewonly=True)
class ParentFeatureThingPivot(Base):
__tablename__ = 'parent_feature_thing'
parent_feature_id = Column(ForeignKey('parent_feature.id', ondelete='CASCADE'), primary_key=True)
thing_id = Column(ForeignKey('thing_id.id', ondelete='CASCADE'), primary_key=True)
class Thing(Base):
__tablename__ = 'thing'
id = Column(types.Integer, primary_key=True, autoincrement=True)
name = Column(types.Unicode, nullable=False)direction = desc # or asc
result = (
pg.query(ParentFeature)
.join(ParentFeature.parent, ParentFeature.unordered_shows)
.options(
joinedload(ParentFeature.parent),
joinedload(ParentFeature.unordered_shows),
)
.filter(Parent.id == 3)
.order_by(direction(Thing.name))
)
from sqlalchemy import asc, Column, create_engine, desc, ForeignKey, types
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import joinedload, relationship, sessionmaker
Base = declarative_base()
class Parent(Base):
__tablename__ = 'parent'
id = Column(types.Integer, primary_key=True, autoincrement=True)
parent_feature = relationship('ParentFeature', lazy='joined', uselist=False)
class Thing(Base):
__tablename__ = 'thing'
id = Column(types.Integer, primary_key=True, autoincrement=True)
name = Column(types.Unicode, nullable=False)
class ParentFeature(Base):
__tablename__ = 'parent_feature'
id = Column(types.Integer, primary_key=True, autoincrement=True)
parent_id = Column(ForeignKey('parent.id'), nullable=False, index=True)
parent = relationship('Parent', uselist=False)
unordered_things = relationship('Thing', secondary='parent_feature_thing')
things = relationship('Thing', secondary='parent_feature_thing', order_by=Thing.name, viewonly=True)
class ParentFeatureThingPivot(Base):
__tablename__ = 'parent_feature_thing'
parent_feature_id = Column(ForeignKey('parent_feature.id'), primary_key=True)
thing_id = Column(ForeignKey('thing.id'), primary_key=True)
engine = create_engine('sqlite:///')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
models = [
Parent(id=1),
Parent(id=2),
Thing(id=1, name='aaaa'),
Thing(id=2, name='bbbb'),
Thing(id=3, name='cccc'),
ParentFeature(id=1, parent_id=1),
ParentFeature(id=2, parent_id=2),
ParentFeatureThingPivot(parent_feature_id=2, thing_id=1),
ParentFeatureThingPivot(parent_feature_id=2, thing_id=2),
ParentFeatureThingPivot(parent_feature_id=2, thing_id=3),
]
for model in models:
session.add(model)
session.flush()
parent = session.query(Parent).all()[1]
things = [thing.name for thing in parent.parent_feature.things]
things_check = ['aaaa', 'bbbb', 'cccc']
print('{} == {}'.format(things, things_check))
assert things == things_check
for direction in (asc, desc):
things_check = ['aaaa', 'bbbb', 'cccc']
if direction == desc:
things_check = list(reversed(things_check))
parent_feature = (
session.query(ParentFeature)
.join(ParentFeature.parent, ParentFeature.unordered_things)
.options(
joinedload(ParentFeature.parent),
joinedload(ParentFeature.unordered_things),
)
.filter(Parent.id == 2)
.order_by(asc(Thing.name))
.one()
)
things = [thing.name for thing in parent_feature.things]
print('{} == {}'.format(things, things_check))
assert things == things_check
the fact that you are changing the order of things_check seems to
imply you want the order of parent_feature.things to change also....
but you're not changing the query.
in which case you would use contains_eager()